Merge tag 'dma-mapping-5.9-1' of git://git.infradead.org/users/hch/dma-mapping
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Aug 2020 17:48:17 +0000 (10:48 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 20 Aug 2020 17:48:17 +0000 (10:48 -0700)
Pull dma-mapping fixes from Christoph Hellwig:
 "Fix more fallout from the dma-pool changes (Nicolas Saenz Julienne,
  me)"

* tag 'dma-mapping-5.9-1' of git://git.infradead.org/users/hch/dma-mapping:
  dma-pool: Only allocate from CMA when in same memory zone
  dma-pool: fix coherent pool allocations for IOMMU mappings

793 files changed:
.mailmap
Documentation/admin-guide/hw-vuln/multihit.rst
Documentation/admin-guide/pm/intel_pstate.rst
Documentation/bpf/index.rst
Documentation/devicetree/bindings/arm/arm,integrator.yaml
Documentation/devicetree/bindings/arm/arm,realview.yaml
Documentation/devicetree/bindings/arm/arm,vexpress-juno.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,bcm11351.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,bcm21664.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,bcm23550.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,cygnus.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,hr2.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,ns2.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,nsp.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,stingray.yaml
Documentation/devicetree/bindings/arm/bcm/brcm,vulcan-soc.yaml
Documentation/devicetree/bindings/arm/coresight-cti.yaml
Documentation/devicetree/bindings/arm/cpus.yaml
Documentation/devicetree/bindings/arm/fsl.yaml
Documentation/devicetree/bindings/arm/intel,keembay.yaml
Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.yaml
Documentation/devicetree/bindings/bus/baikal,bt1-apb.yaml
Documentation/devicetree/bindings/bus/baikal,bt1-axi.yaml
Documentation/devicetree/bindings/clock/idt,versaclock5.yaml
Documentation/devicetree/bindings/clock/ingenic,cgu.yaml
Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
Documentation/devicetree/bindings/clock/renesas,cpg-clocks.yaml
Documentation/devicetree/bindings/clock/sprd,sc9863a-clk.yaml
Documentation/devicetree/bindings/display/brcm,bcm2835-hdmi.yaml
Documentation/devicetree/bindings/display/bridge/nwl-dsi.yaml
Documentation/devicetree/bindings/display/bridge/renesas,lvds.yaml
Documentation/devicetree/bindings/display/bridge/simple-bridge.yaml
Documentation/devicetree/bindings/display/dsi-controller.yaml
Documentation/devicetree/bindings/display/ilitek,ili9486.yaml
Documentation/devicetree/bindings/display/ingenic,ipu.yaml
Documentation/devicetree/bindings/display/ingenic,lcd.yaml
Documentation/devicetree/bindings/display/msm/gmu.yaml
Documentation/devicetree/bindings/display/panel/asus,z00t-tm5p5-nt35596.yaml
Documentation/devicetree/bindings/display/panel/boe,tv101wum-nl6.yaml
Documentation/devicetree/bindings/display/panel/elida,kd35t133.yaml
Documentation/devicetree/bindings/display/panel/feixin,k101-im2ba02.yaml
Documentation/devicetree/bindings/display/panel/ilitek,ili9322.yaml
Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml
Documentation/devicetree/bindings/display/panel/leadtek,ltk050h3146w.yaml
Documentation/devicetree/bindings/display/panel/leadtek,ltk500hd1829.yaml
Documentation/devicetree/bindings/display/panel/novatek,nt35510.yaml
Documentation/devicetree/bindings/display/panel/panel-dsi-cm.yaml
Documentation/devicetree/bindings/display/panel/panel-timing.yaml
Documentation/devicetree/bindings/display/panel/raydium,rm68200.yaml
Documentation/devicetree/bindings/display/panel/samsung,s6e88a0-ams452ef01.yaml
Documentation/devicetree/bindings/display/panel/visionox,rm69299.yaml
Documentation/devicetree/bindings/display/st,stm32-dsi.yaml
Documentation/devicetree/bindings/display/ti/ti,j721e-dss.yaml
Documentation/devicetree/bindings/dsp/fsl,dsp.yaml
Documentation/devicetree/bindings/example-schema.yaml
Documentation/devicetree/bindings/fsi/ibm,fsi2spi.yaml
Documentation/devicetree/bindings/gpio/brcm,xgs-iproc-gpio.yaml
Documentation/devicetree/bindings/gpio/renesas,rcar-gpio.yaml
Documentation/devicetree/bindings/gpu/vivante,gc.yaml
Documentation/devicetree/bindings/hwmon/adi,axi-fan-control.yaml
Documentation/devicetree/bindings/i2c/i2c-imx.yaml
Documentation/devicetree/bindings/i2c/i2c-pxa.yaml
Documentation/devicetree/bindings/iio/adc/adi,ad7606.yaml
Documentation/devicetree/bindings/iio/adc/maxim,max1238.yaml
Documentation/devicetree/bindings/iio/adc/qcom,spmi-vadc.yaml
Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml
Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml
Documentation/devicetree/bindings/iio/chemical/atlas,sensor.yaml
Documentation/devicetree/bindings/iio/dac/adi,ad5770r.yaml
Documentation/devicetree/bindings/iio/light/vishay,vcnl4000.yaml
Documentation/devicetree/bindings/iio/magnetometer/asahi-kasei,ak8975.yaml
Documentation/devicetree/bindings/iio/proximity/vishay,vcnl3020.yaml
Documentation/devicetree/bindings/iio/temperature/adi,ltc2983.yaml
Documentation/devicetree/bindings/input/imx-keypad.yaml
Documentation/devicetree/bindings/input/touchscreen/cypress,cy8ctma140.yaml
Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.yaml
Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
Documentation/devicetree/bindings/interconnect/fsl,imx8m-noc.yaml
Documentation/devicetree/bindings/interconnect/qcom,sc7180.yaml
Documentation/devicetree/bindings/interconnect/qcom,sdm845.yaml
Documentation/devicetree/bindings/interrupt-controller/arm,gic.yaml
Documentation/devicetree/bindings/interrupt-controller/ingenic,intc.yaml
Documentation/devicetree/bindings/interrupt-controller/mti,gic.yaml
Documentation/devicetree/bindings/leds/backlight/qcom-wled.yaml
Documentation/devicetree/bindings/mailbox/fsl,mu.yaml
Documentation/devicetree/bindings/mailbox/qcom-ipcc.yaml
Documentation/devicetree/bindings/media/allwinner,sun8i-a83t-de2-rotate.yaml
Documentation/devicetree/bindings/media/allwinner,sun8i-h3-deinterlace.yaml
Documentation/devicetree/bindings/media/i2c/adv7180.yaml
Documentation/devicetree/bindings/media/i2c/dongwoon,dw9768.yaml
Documentation/devicetree/bindings/media/i2c/imi,rdacm2x-gmsl.yaml
Documentation/devicetree/bindings/media/i2c/maxim,max9286.yaml
Documentation/devicetree/bindings/media/i2c/ov8856.yaml
Documentation/devicetree/bindings/media/renesas,csi2.yaml
Documentation/devicetree/bindings/media/rockchip-vpu.yaml
Documentation/devicetree/bindings/media/xilinx/xlnx,csi2rxss.yaml
Documentation/devicetree/bindings/memory-controllers/fsl/mmdc.yaml
Documentation/devicetree/bindings/memory-controllers/ingenic,nemc.yaml
Documentation/devicetree/bindings/memory-controllers/renesas,rpc-if.yaml
Documentation/devicetree/bindings/mfd/cirrus,madera.yaml
Documentation/devicetree/bindings/mfd/cros-ec.txt [deleted file]
Documentation/devicetree/bindings/mfd/gateworks-gsc.yaml
Documentation/devicetree/bindings/mfd/google,cros-ec.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/khadas,mcu.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/st,stm32-lptimer.yaml
Documentation/devicetree/bindings/mfd/st,stmfx.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/st,stpmic1.yaml
Documentation/devicetree/bindings/mfd/stmfx.txt [deleted file]
Documentation/devicetree/bindings/mfd/ti,j721e-system-controller.yaml
Documentation/devicetree/bindings/mfd/twl-family.txt
Documentation/devicetree/bindings/mfd/wlf,arizona.yaml
Documentation/devicetree/bindings/mmc/amlogic,meson-mx-sdhc.yaml
Documentation/devicetree/bindings/mmc/ingenic,mmc.yaml
Documentation/devicetree/bindings/mmc/renesas,sdhi.yaml
Documentation/devicetree/bindings/mtd/arasan,nand-controller.yaml
Documentation/devicetree/bindings/mtd/gpmi-nand.yaml
Documentation/devicetree/bindings/mtd/mxc-nand.yaml
Documentation/devicetree/bindings/mtd/st,stm32-fmc2-nand.yaml
Documentation/devicetree/bindings/net/dsa/dsa.yaml
Documentation/devicetree/bindings/net/qcom,ipa.yaml
Documentation/devicetree/bindings/net/socionext,uniphier-ave4.yaml
Documentation/devicetree/bindings/net/stm32-dwmac.yaml
Documentation/devicetree/bindings/net/ti,cpsw-switch.yaml
Documentation/devicetree/bindings/net/ti,k3-am654-cpsw-nuss.yaml
Documentation/devicetree/bindings/nvmem/imx-ocotp.yaml
Documentation/devicetree/bindings/nvmem/qcom,qfprom.yaml
Documentation/devicetree/bindings/pci/ti,j721e-pci-ep.yaml
Documentation/devicetree/bindings/pci/ti,j721e-pci-host.yaml
Documentation/devicetree/bindings/phy/amlogic,meson-g12a-usb2-phy.yaml
Documentation/devicetree/bindings/phy/phy-rockchip-inno-usb2.yaml
Documentation/devicetree/bindings/phy/qcom,qmp-phy.yaml
Documentation/devicetree/bindings/phy/qcom,qmp-usb3-dp-phy.yaml
Documentation/devicetree/bindings/phy/qcom,qusb2-phy.yaml
Documentation/devicetree/bindings/phy/socionext,uniphier-pcie-phy.yaml
Documentation/devicetree/bindings/phy/socionext,uniphier-usb3hs-phy.yaml
Documentation/devicetree/bindings/phy/socionext,uniphier-usb3ss-phy.yaml
Documentation/devicetree/bindings/phy/ti,phy-j721e-wiz.yaml
Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/aspeed,ast2600-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/ingenic,pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/pinctrl-stmfx.txt [deleted file]
Documentation/devicetree/bindings/pinctrl/qcom,ipq6018-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/qcom,sm8250-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/st,stm32-pinctrl.yaml
Documentation/devicetree/bindings/power/power-domain.yaml
Documentation/devicetree/bindings/power/supply/gpio-charger.yaml
Documentation/devicetree/bindings/regulator/qcom,smd-rpm-regulator.yaml
Documentation/devicetree/bindings/regulator/qcom-labibb-regulator.yaml
Documentation/devicetree/bindings/remoteproc/ti,k3-dsp-rproc.yaml
Documentation/devicetree/bindings/reset/fsl,imx7-src.yaml
Documentation/devicetree/bindings/rtc/ingenic,rtc.yaml
Documentation/devicetree/bindings/serial/ingenic,uart.yaml
Documentation/devicetree/bindings/soc/microchip/atmel,at91rm9200-tcb.yaml
Documentation/devicetree/bindings/soc/qcom/qcom,geni-se.yaml
Documentation/devicetree/bindings/sound/amlogic,aiu.yaml
Documentation/devicetree/bindings/sound/amlogic,g12a-toacodec.yaml
Documentation/devicetree/bindings/sound/cirrus,cs42l51.yaml
Documentation/devicetree/bindings/sound/ingenic,aic.yaml
Documentation/devicetree/bindings/sound/maxim,max98390.yaml
Documentation/devicetree/bindings/sound/nvidia,tegra186-dspk.yaml
Documentation/devicetree/bindings/sound/nvidia,tegra210-dmic.yaml
Documentation/devicetree/bindings/sound/nvidia,tegra210-i2s.yaml
Documentation/devicetree/bindings/sound/rockchip-i2s.yaml
Documentation/devicetree/bindings/sound/rockchip-spdif.yaml
Documentation/devicetree/bindings/sound/tas2770.yaml
Documentation/devicetree/bindings/sound/ti,j721e-cpb-audio.yaml
Documentation/devicetree/bindings/sound/ti,j721e-cpb-ivi-audio.yaml
Documentation/devicetree/bindings/sound/tlv320adcx140.yaml
Documentation/devicetree/bindings/spi/allwinner,sun6i-a31-spi.yaml
Documentation/devicetree/bindings/spi/fsl-imx-cspi.yaml
Documentation/devicetree/bindings/spi/mikrotik,rb4xx-spi.yaml
Documentation/devicetree/bindings/spi/spi-fsl-lpspi.yaml
Documentation/devicetree/bindings/spi/spi-mux.yaml
Documentation/devicetree/bindings/spi/spi-rockchip.yaml
Documentation/devicetree/bindings/thermal/thermal-cooling-devices.yaml
Documentation/devicetree/bindings/thermal/thermal-idle.yaml
Documentation/devicetree/bindings/timer/fsl,imxgpt.yaml
Documentation/devicetree/bindings/timer/ingenic,tcu.yaml
Documentation/devicetree/bindings/timer/snps,dw-apb-timer.yaml
Documentation/devicetree/bindings/trivial-devices.yaml
Documentation/devicetree/bindings/usb/dwc2.yaml
Documentation/devicetree/bindings/usb/generic-ehci.yaml
Documentation/devicetree/bindings/usb/ingenic,musb.yaml
Documentation/devicetree/bindings/usb/nvidia,tegra-xudc.yaml
Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
Documentation/devicetree/bindings/usb/ti,keystone-dwc3.yaml
Documentation/devicetree/bindings/vendor-prefixes.yaml
Documentation/driver-api/index.rst
Documentation/driver-api/smsc_ece1099.rst [deleted file]
Documentation/networking/bonding.rst
MAINTAINERS
Makefile
arch/Kconfig
arch/alpha/include/asm/core_apecs.h
arch/alpha/include/asm/core_cia.h
arch/alpha/include/asm/core_lca.h
arch/alpha/include/asm/core_marvel.h
arch/alpha/include/asm/core_mcpcia.h
arch/alpha/include/asm/core_t2.h
arch/alpha/include/asm/io.h
arch/alpha/include/asm/io_trivial.h
arch/alpha/include/asm/jensen.h
arch/alpha/include/asm/machvec.h
arch/alpha/kernel/core_marvel.c
arch/alpha/kernel/io.c
arch/alpha/kernel/syscalls/syscall.tbl
arch/arm/configs/am200epdkit_defconfig
arch/arm/include/asm/vdso/gettimeofday.h
arch/arm/tools/syscall.tbl
arch/arm64/include/asm/unistd32.h
arch/arm64/include/asm/vdso/compat_gettimeofday.h
arch/arm64/include/asm/vdso/gettimeofday.h
arch/ia64/include/asm/pgtable.h
arch/ia64/kernel/syscalls/syscall.tbl
arch/m68k/Kconfig
arch/m68k/Kconfig.machine
arch/m68k/kernel/syscalls/syscall.tbl
arch/microblaze/kernel/syscalls/syscall.tbl
arch/mips/configs/cu1000-neo_defconfig
arch/mips/include/asm/vdso/gettimeofday.h
arch/mips/kernel/syscalls/syscall_n32.tbl
arch/mips/kernel/syscalls/syscall_n64.tbl
arch/mips/kernel/syscalls/syscall_o32.tbl
arch/openrisc/include/asm/io.h
arch/openrisc/include/asm/uaccess.h
arch/openrisc/kernel/setup.c
arch/openrisc/kernel/signal.c
arch/openrisc/kernel/smp.c
arch/openrisc/kernel/stacktrace.c
arch/openrisc/kernel/vmlinux.lds.S
arch/openrisc/mm/tlb.c
arch/parisc/include/asm/io.h
arch/parisc/include/asm/pgalloc.h
arch/parisc/kernel/syscalls/syscall.tbl
arch/parisc/lib/iomap.c
arch/powerpc/kernel/iomap.c
arch/powerpc/kernel/syscalls/syscall.tbl
arch/powerpc/mm/book3s64/hash_utils.c
arch/powerpc/mm/book3s64/pkeys.c
arch/riscv/include/asm/vdso/gettimeofday.h
arch/riscv/kernel/head.S
arch/s390/kernel/syscalls/syscall.tbl
arch/sh/Kconfig
arch/sh/Makefile
arch/sh/boards/Kconfig
arch/sh/boards/board-sh2007.c
arch/sh/boards/mach-cayman/Makefile [deleted file]
arch/sh/boards/mach-cayman/irq.c [deleted file]
arch/sh/boards/mach-cayman/panic.c [deleted file]
arch/sh/boards/mach-cayman/setup.c [deleted file]
arch/sh/boards/mach-landisk/setup.c
arch/sh/configs/cayman_defconfig [deleted file]
arch/sh/configs/dreamcast_defconfig
arch/sh/configs/espt_defconfig
arch/sh/configs/hp6xx_defconfig
arch/sh/configs/landisk_defconfig
arch/sh/configs/lboxre2_defconfig
arch/sh/configs/microdev_defconfig
arch/sh/configs/migor_defconfig
arch/sh/configs/r7780mp_defconfig
arch/sh/configs/r7785rp_defconfig
arch/sh/configs/rts7751r2d1_defconfig
arch/sh/configs/rts7751r2dplus_defconfig
arch/sh/configs/se7206_defconfig
arch/sh/configs/se7343_defconfig
arch/sh/configs/se7619_defconfig
arch/sh/configs/se7705_defconfig
arch/sh/configs/se7750_defconfig
arch/sh/configs/se7751_defconfig
arch/sh/configs/secureedge5410_defconfig
arch/sh/configs/sh03_defconfig
arch/sh/configs/sh7710voipgw_defconfig
arch/sh/configs/sh7757lcr_defconfig
arch/sh/configs/sh7763rdp_defconfig
arch/sh/configs/shmin_defconfig
arch/sh/configs/titan_defconfig
arch/sh/drivers/pci/Makefile
arch/sh/drivers/pci/common.c
arch/sh/drivers/pci/fixups-cayman.c [deleted file]
arch/sh/drivers/pci/pci-sh7780.c
arch/sh/drivers/pci/pci.c
arch/sh/include/asm/adc.h
arch/sh/include/asm/addrspace.h
arch/sh/include/asm/bitops.h
arch/sh/include/asm/cache.h
arch/sh/include/asm/cacheflush.h
arch/sh/include/asm/dma.h
arch/sh/include/asm/elf.h
arch/sh/include/asm/freq.h
arch/sh/include/asm/futex.h
arch/sh/include/asm/io.h
arch/sh/include/asm/kdebug.h
arch/sh/include/asm/mmu_context.h
arch/sh/include/asm/mmzone.h
arch/sh/include/asm/pci.h
arch/sh/include/asm/processor_32.h
arch/sh/include/asm/smc37c93x.h
arch/sh/include/asm/sparsemem.h
arch/sh/include/asm/stacktrace.h
arch/sh/include/asm/string_32.h
arch/sh/include/asm/syscall_32.h
arch/sh/include/asm/syscalls_32.h
arch/sh/include/asm/thread_info.h
arch/sh/include/asm/uaccess_32.h
arch/sh/include/asm/watchdog.h
arch/sh/kernel/Makefile
arch/sh/kernel/disassemble.c
arch/sh/kernel/dma-coherent.c
arch/sh/kernel/dumpstack.c
arch/sh/kernel/entry-common.S
arch/sh/kernel/io_trapped.c
arch/sh/kernel/iomap.c
arch/sh/kernel/ioport.c
arch/sh/kernel/machvec.c
arch/sh/kernel/perf_callchain.c
arch/sh/kernel/process_32.c
arch/sh/kernel/ptrace_32.c
arch/sh/kernel/stacktrace.c
arch/sh/kernel/syscalls/syscall.tbl
arch/sh/lib/Makefile
arch/sh/lib/delay.c
arch/sh/mm/Makefile
arch/sh/mm/consistent.c
arch/sh/mm/fault.c
arch/sh/mm/init.c
arch/sh/mm/ioremap.c
arch/sh/mm/ioremap.h [new file with mode: 0644]
arch/sh/mm/ioremap_fixed.c
arch/sh/mm/pgtable.c
arch/sh/oprofile/backtrace.c
arch/sh/tools/mach-types
arch/sparc/kernel/syscalls/syscall.tbl
arch/um/Kconfig
arch/x86/Kconfig
arch/x86/boot/compressed/misc.c
arch/x86/boot/string.h
arch/x86/entry/entry_32.S
arch/x86/entry/syscalls/syscall_32.tbl
arch/x86/entry/syscalls/syscall_64.tbl
arch/x86/entry/vdso/vdso32/note.S
arch/x86/events/rapl.c
arch/x86/include/asm/mshyperv.h
arch/x86/include/asm/proto.h
arch/x86/include/asm/segment.h
arch/x86/include/asm/vdso/gettimeofday.h
arch/x86/kernel/alternative.c
arch/x86/kernel/cpu/acrn.c
arch/x86/kernel/cpu/bugs.c
arch/x86/kernel/cpu/mshyperv.c
arch/x86/kernel/crash.c
arch/x86/kernel/fpu/xstate.c
arch/x86/kernel/head_32.S
arch/x86/kernel/process_64.c
arch/x86/kernel/tsc_msr.c
arch/x86/purgatory/Makefile
arch/x86/xen/Kconfig
arch/x86/xen/Makefile
arch/x86/xen/apic.c
arch/x86/xen/enlighten_pv.c
arch/x86/xen/mmu_pv.c
arch/x86/xen/p2m.c
arch/x86/xen/setup.c
arch/x86/xen/smp_pv.c
arch/x86/xen/vdso.h [deleted file]
arch/x86/xen/xen-asm.S
arch/x86/xen/xen-asm_32.S [deleted file]
arch/x86/xen/xen-asm_64.S [deleted file]
arch/x86/xen/xen-head.S
arch/x86/xen/xen-ops.h
arch/xtensa/kernel/syscalls/syscall.tbl
block/blk-flush.c
block/blk-lib.c
crypto/algif_aead.c
crypto/algif_skcipher.c
drivers/acpi/acpi_apd.c
drivers/block/loop.c
drivers/block/rnbd/rnbd-srv-dev.c
drivers/block/rnbd/rnbd-srv-dev.h
drivers/block/rnbd/rnbd-srv.c
drivers/clk/clk-pwm.c
drivers/clk/x86/Makefile
drivers/clk/x86/clk-fch.c [new file with mode: 0644]
drivers/clk/x86/clk-st.c [deleted file]
drivers/clocksource/Kconfig
drivers/clocksource/Makefile
drivers/clocksource/timer-stm32-lp.c [new file with mode: 0644]
drivers/cpufreq/cpufreq.c
drivers/cpufreq/intel_pstate.c
drivers/edac/ie31200_edac.c
drivers/gpu/drm/i915/display/intel_panel.c
drivers/gpu/drm/xen/xen_drm_front.c
drivers/gpu/drm/xen/xen_drm_front.h
drivers/gpu/drm/xen/xen_drm_front_conn.c
drivers/gpu/drm/xen/xen_drm_front_gem.c
drivers/gpu/drm/xen/xen_drm_front_kms.c
drivers/hv/vmbus_drv.c
drivers/hwmon/pwm-fan.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/input/serio/i8042-io.h
drivers/mailbox/bcm-pdc-mailbox.c
drivers/md/md-cluster.c
drivers/md/md.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/ab3100-core.c
drivers/mfd/ab3100-otp.c
drivers/mfd/ab8500-debugfs.c
drivers/mfd/altera-sysmgr.c
drivers/mfd/arizona-core.c
drivers/mfd/atmel-smc.c
drivers/mfd/axp20x-i2c.c
drivers/mfd/cros_ec_dev.c
drivers/mfd/da9063-core.c
drivers/mfd/da9063-i2c.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/dln2.c
drivers/mfd/hi6421-pmic-core.c
drivers/mfd/intel-lpss-pci.c
drivers/mfd/intel_soc_pmic_mrfld.c
drivers/mfd/kempld-core.c
drivers/mfd/khadas-mcu.c [new file with mode: 0644]
drivers/mfd/lm3533-ctrlbank.c
drivers/mfd/lp873x.c
drivers/mfd/lp87565.c
drivers/mfd/madera-core.c
drivers/mfd/madera-i2c.c
drivers/mfd/max14577.c
drivers/mfd/mfd-core.c
drivers/mfd/motorola-cpcap.c
drivers/mfd/omap-usb-host.c
drivers/mfd/omap-usb-tll.c
drivers/mfd/rave-sp.c
drivers/mfd/rn5t618.c
drivers/mfd/si476x-cmd.c
drivers/mfd/si476x-i2c.c
drivers/mfd/smsc-ece1099.c [deleted file]
drivers/mfd/sprd-sc27xx-spi.c
drivers/mfd/stm32-lptimer.c
drivers/mfd/syscon.c
drivers/mfd/tc3589x.c
drivers/mfd/ti_am335x_tscadc.c
drivers/mfd/tps65010.c
drivers/mfd/tps65086.c
drivers/mfd/tps65217.c
drivers/mfd/tps65218.c
drivers/mfd/tps6586x.c
drivers/mfd/tps65912-core.c
drivers/mfd/tps65912-i2c.c
drivers/mfd/tps65912-spi.c
drivers/mfd/twl4030-irq.c
drivers/mfd/wm831x-core.c
drivers/mfd/wm8350-core.c
drivers/mfd/wm8400-core.c
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_main.c
drivers/net/ethernet/3com/3c574_cs.c
drivers/net/ethernet/8390/axnet_cs.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
drivers/net/ethernet/intel/i40e/i40e_common.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/igc/igc_main.c
drivers/net/ethernet/intel/igc/igc_ptp.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
drivers/net/ethernet/sfc/ef100_rx.c
drivers/net/ethernet/sfc/ef100_rx.h
drivers/net/ethernet/sfc/efx.h
drivers/net/ethernet/sfc/net_driver.h
drivers/net/ethernet/sfc/rx_common.c
drivers/net/fddi/skfp/cfm.c
drivers/net/fddi/skfp/fplustm.c
drivers/net/fddi/skfp/hwmtm.c
drivers/net/fddi/skfp/smt.c
drivers/net/ipvlan/ipvlan_main.c
drivers/net/wan/dlci.c
drivers/net/wan/hdlc.c
drivers/net/wan/hdlc_x25.c
drivers/net/wireless/realtek/rtl818x/rtl8180/rtl8180.h
drivers/ntb/hw/intel/ntb_hw_gen1.c
drivers/ntb/hw/intel/ntb_hw_gen3.h
drivers/ntb/hw/intel/ntb_hw_intel.h
drivers/nvdimm/btt.c
drivers/nvdimm/pmem.c
drivers/pwm/core.c
drivers/pwm/pwm-bcm-iproc.c
drivers/pwm/pwm-bcm-kona.c
drivers/pwm/pwm-clps711x.c
drivers/pwm/pwm-imx-tpm.c
drivers/pwm/pwm-imx27.c
drivers/pwm/pwm-iqs620a.c
drivers/pwm/pwm-mediatek.c
drivers/pwm/pwm-omap-dmtimer.c
drivers/pwm/pwm-sifive.c
drivers/pwm/pwm-stm32-lp.c
drivers/pwm/pwm-sun4i.c
drivers/pwm/pwm-tiecap.c
drivers/pwm/pwm-tiehrpwm.c
drivers/pwm/sysfs.c
drivers/scsi/fcoe/fcoe_ctlr.c
drivers/scsi/libfc/fc_disc.c
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_bsg.c
drivers/scsi/lpfc/lpfc_ct.c
drivers/scsi/lpfc/lpfc_els.c
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_nportdisc.c
drivers/scsi/lpfc/lpfc_nvmet.c
drivers/scsi/lpfc/lpfc_sli.c
drivers/scsi/lpfc/lpfc_version.h
drivers/scsi/scsi_transport_sas.c
drivers/scsi/sd.c
drivers/scsi/sd.h
drivers/scsi/sd_zbc.c
drivers/sh/clk/cpg.c
drivers/spi/Kconfig
drivers/spi/spi-stm32.c
drivers/spi/spi.c
drivers/target/iscsi/iscsi_target_transport.c
drivers/thermal/Kconfig
drivers/thermal/Makefile
drivers/thermal/khadas_mcu_fan.c [new file with mode: 0644]
drivers/vfio/pci/vfio_pci_private.h
drivers/vfio/pci/vfio_pci_rdwr.c
drivers/vfio/vfio_iommu_type1.c
drivers/video/backlight/pwm_bl.c
drivers/video/fbdev/ssd1307fb.c
drivers/virtio/virtio_pci_modern.c
drivers/xen/Kconfig
drivers/xen/gntdev-dmabuf.c
fs/9p/v9fs.c
fs/9p/vfs_inode.c
fs/9p/vfs_inode_dotl.c
fs/afs/fs_operation.c
fs/autofs/dev-ioctl.c
fs/cifs/connect.c
fs/cifs/smb2inode.c
fs/cifs/smb2pdu.c
fs/io_uring.c
fs/namei.c
fs/nfs/Makefile
fs/nfs/blocklayout/rpc_pipefs.c
fs/nfs/client.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/file.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/fs_context.c
fs/nfs/inode.c
fs/nfs/nfs42.h
fs/nfs/nfs42proc.c
fs/nfs/nfs42xattr.c [new file with mode: 0644]
fs/nfs/nfs42xdr.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4file.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4super.c
fs/nfs/nfs4trace.h
fs/nfs/nfs4xdr.c
fs/nfs/nfstrace.h
fs/nfs/pnfs.c
fs/nfs/pnfs.h
include/asm-generic/io.h
include/asm-generic/iomap.h
include/asm-generic/mshyperv.h
include/asm-generic/pgalloc.h
include/asm-generic/vmlinux.lds.h
include/linux/compat.h
include/linux/cpufreq.h
include/linux/dma-debug.h
include/linux/fs.h
include/linux/huge_mm.h
include/linux/hw_breakpoint.h
include/linux/io-64-nonatomic-hi-lo.h
include/linux/io-64-nonatomic-lo-hi.h
include/linux/memcontrol.h
include/linux/mfd/core.h
include/linux/mfd/da9055/pdata.h
include/linux/mfd/da9063/core.h
include/linux/mfd/da9063/registers.h
include/linux/mfd/hi6421-pmic.h
include/linux/mfd/khadas-mcu.h [new file with mode: 0644]
include/linux/mfd/lp873x.h
include/linux/mfd/lp87565.h
include/linux/mfd/madera/pdata.h
include/linux/mfd/max77693-private.h
include/linux/mfd/smsc.h [deleted file]
include/linux/mfd/stm32-lptimer.h
include/linux/mfd/ti_am335x_tscadc.h
include/linux/mfd/tps65086.h
include/linux/mfd/tps65217.h
include/linux/mfd/tps65218.h
include/linux/mfd/tps65912.h
include/linux/mm.h
include/linux/mm_inline.h
include/linux/mm_types.h
include/linux/module.h
include/linux/moduleparam.h
include/linux/netfilter_ipv6.h
include/linux/nfs4.h
include/linux/nfs_fs.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h
include/linux/pagemap.h
include/linux/pgtable.h
include/linux/phylink.h
include/linux/platform_data/clk-fch.h [new file with mode: 0644]
include/linux/platform_data/clk-st.h [deleted file]
include/linux/posix-timers.h
include/linux/pwm.h
include/linux/sched.h
include/linux/sched/user.h
include/linux/sunrpc/xprt.h
include/linux/syscalls.h
include/linux/sysctl.h
include/target/iscsi/iscsi_transport.h
include/uapi/linux/nfs_fs.h
include/vdso/datapage.h
include/vdso/vsyscall.h
include/xen/interface/io/displif.h
init/init_task.c
kernel/Makefile
kernel/bpf/stackmap.c
kernel/dma/Kconfig
kernel/dma/debug.c
kernel/events/core.c
kernel/futex.c
kernel/irq/manage.c
kernel/irq/pm.c
kernel/kexec_file.c
kernel/module.c
kernel/sched/core.c
kernel/sched/sched.h
kernel/signal.c
kernel/sys_ni.c
kernel/sysctl_binary.c [deleted file]
kernel/task_work.c
kernel/time/Kconfig
kernel/time/alarmtimer.c
kernel/time/posix-cpu-timers.c
kernel/time/sched_clock.c
kernel/time/timekeeping.c
kernel/time/timekeeping_internal.h
kernel/time/timer.c
kernel/time/vsyscall.c
kernel/watch_queue.c
lib/Makefile
lib/iomap.c
lib/lz4/lz4_compress.c
lib/lz4/lz4_decompress.c
lib/lz4/lz4defs.h
lib/lz4/lz4hc_compress.c
lib/vdso/gettimeofday.c
mm/compaction.c
mm/filemap.c
mm/frontswap.c
mm/gup.c
mm/internal.h
mm/kmemleak.c
mm/list_lru.c
mm/memcontrol.c
mm/memory.c
mm/memory_hotplug.c
mm/mempolicy.c
mm/mempool.c
mm/migrate.c
mm/mlock.c
mm/page_alloc.c
mm/page_counter.c
mm/page_io.c
mm/page_vma_mapped.c
mm/rmap.c
mm/swap.c
mm/swap_state.c
mm/swapfile.c
mm/vmscan.c
mm/vmstat.c
mm/workingset.c
net/9p/trans_fd.c
net/bridge/netfilter/ebtables.c
net/bridge/netfilter/nf_conntrack_bridge.c
net/can/j1939/socket.c
net/can/j1939/transport.c
net/core/dev.c
net/core/devlink.c
net/core/filter.c
net/core/skbuff.c
net/ipv6/netfilter.c
net/mptcp/protocol.c
net/netfilter/nf_tables_api.c
net/netfilter/nft_compat.c
net/netfilter/nft_exthdr.c
net/qrtr/qrtr.c
net/sunrpc/rpc_pipe.c
net/sunrpc/xprt.c
net/tipc/Kconfig
net/tipc/netlink_compat.c
scripts/checkkconfigsymbols.py
scripts/checkpatch.pl
scripts/kconfig/images.c
scripts/kconfig/images.h
scripts/kconfig/lexer.l
scripts/kconfig/qconf.cc
scripts/kconfig/qconf.h
scripts/kconfig/symbol.c
sound/pci/echoaudio/echoaudio.c
sound/pci/echoaudio/echoaudio.h
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/usb/card.h
sound/usb/mixer_maps.c
sound/usb/mixer_quirks.c
sound/usb/mixer_us16x08.c
sound/usb/pcm.c
sound/usb/quirks-table.h
sound/usb/quirks.c
sound/usb/stream.c
tools/arch/s390/include/uapi/asm/kvm.h
tools/bpf/bpftool/btf_dumper.c
tools/bpf/bpftool/gen.c
tools/bpf/bpftool/link.c
tools/bpf/bpftool/main.h
tools/bpf/bpftool/prog.c
tools/build/Makefile.feature
tools/build/feature/Makefile
tools/build/feature/test-libdebuginfod.c [new file with mode: 0644]
tools/include/uapi/linux/kvm.h
tools/include/uapi/linux/vhost.h
tools/lib/bpf/bpf_helpers.h
tools/lib/bpf/btf.c
tools/lib/bpf/btf.h
tools/lib/bpf/btf_dump.c
tools/lib/bpf/libbpf.c
tools/lib/bpf/libbpf.map
tools/lib/perf/Documentation/libperf-counting.txt
tools/lib/perf/Documentation/libperf-sampling.txt
tools/lib/perf/Documentation/libperf.txt
tools/perf/Documentation/perf-config.txt
tools/perf/Documentation/perf-ftrace.txt
tools/perf/Makefile.config
tools/perf/Makefile.perf
tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
tools/perf/arch/s390/entry/syscalls/syscall.tbl
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
tools/perf/bench/find-bit-bench.c
tools/perf/bench/mem-functions.c
tools/perf/bench/numa.c
tools/perf/builtin-ftrace.c
tools/perf/builtin-sched.c
tools/perf/check-headers.sh
tools/perf/pmu-events/arch/powerpc/power9/metrics.json
tools/perf/tests/shell/record+script_probe_vfs_getname.sh
tools/perf/trace/beauty/include/linux/socket.h [new file with mode: 0644]
tools/perf/trace/beauty/sockaddr.c
tools/perf/trace/beauty/socket.sh [new file with mode: 0755]
tools/perf/util/Build
tools/perf/util/build-id.c
tools/perf/util/debug.c
tools/perf/util/dso.c
tools/perf/util/dso.h
tools/perf/util/header.c
tools/perf/util/machine.c
tools/perf/util/map.c
tools/perf/util/parse-sublevel-options.c [new file with mode: 0644]
tools/perf/util/parse-sublevel-options.h [new file with mode: 0644]
tools/perf/util/symbol-elf.c
tools/perf/util/symbol.c
tools/testing/selftests/bpf/prog_tests/bpf_obj_id.c
tools/testing/selftests/bpf/prog_tests/btf_dump.c
tools/testing/selftests/bpf/prog_tests/core_extern.c
tools/testing/selftests/bpf/prog_tests/core_reloc.c
tools/testing/selftests/bpf/prog_tests/fexit_bpf2bpf.c
tools/testing/selftests/bpf/prog_tests/flow_dissector.c
tools/testing/selftests/bpf/prog_tests/global_data.c
tools/testing/selftests/bpf/prog_tests/mmap.c
tools/testing/selftests/bpf/prog_tests/prog_run_xattr.c
tools/testing/selftests/bpf/prog_tests/sk_lookup.c
tools/testing/selftests/bpf/prog_tests/skb_ctx.c
tools/testing/selftests/bpf/prog_tests/varlen.c
tools/testing/selftests/bpf/progs/core_reloc_types.h
tools/testing/selftests/bpf/progs/test_tcpbpf_kern.c
tools/testing/selftests/bpf/progs/test_varlen.c
tools/testing/selftests/bpf/test_btf.c
tools/testing/selftests/bpf/test_progs.h
tools/testing/selftests/exec/.gitignore
tools/testing/selftests/exec/Makefile
tools/testing/selftests/exec/non-regular.c [new file with mode: 0644]
tools/testing/selftests/net/icmp_redirect.sh
tools/testing/selftests/netfilter/nft_flowtable.sh
tools/testing/selftests/seccomp/seccomp_bpf.c

index 83d8d01..97fd835 100644 (file)
--- a/.mailmap
+++ b/.mailmap
 Aaron Durbin <adurbin@google.com>
 Adam Oldham <oldhamca@gmail.com>
 Adam Radford <aradford@gmail.com>
-Adrian Bunk <bunk@stusta.de>
 Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com>
+Adrian Bunk <bunk@stusta.de>
 Alan Cox <alan@lxorguk.ukuu.org.uk>
 Alan Cox <root@hraefn.swansea.linux.org.uk>
-Aleksey Gorelov <aleksey_gorelov@phoenix.com>
 Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com>
-Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@intel.com>
-Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@linaro.org>
+Aleksey Gorelov <aleksey_gorelov@phoenix.com>
 Alexander Lobakin <alobakin@pm.me> <alobakin@dlink.ru>
 Alexander Lobakin <alobakin@pm.me> <alobakin@marvell.com>
 Alexander Lobakin <alobakin@pm.me> <bloodyreaper@yandex.ru>
 Alexandre Belloni <alexandre.belloni@bootlin.com> <alexandre.belloni@free-electrons.com>
-Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com>
 Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com>
 Alexei Starovoitov <ast@kernel.org> <ast@fb.com>
+Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com>
+Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@intel.com>
+Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@linaro.org>
 Al Viro <viro@ftp.linux.org.uk>
 Al Viro <viro@zenIV.linux.org.uk>
 Andi Shyti <andi@etezian.org> <andi.shyti@samsung.com>
 Andreas Herrmann <aherrman@de.ibm.com>
-Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
 Andrew Morton <akpm@linux-foundation.org>
-Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com>
 Andrew Murray <amurray@thegoodpenguin.co.uk> <amurray@embedded-bits.co.uk>
+Andrew Murray <amurray@thegoodpenguin.co.uk> <andrew.murray@arm.com>
 Andrew Vasquez <andrew.vasquez@qlogic.com>
+Andrey Ryabinin <ryabinin.a.a@gmail.com> <a.ryabinin@samsung.com>
 Andy Adamson <andros@citi.umich.edu>
 Antoine Tenart <antoine.tenart@free-electrons.com>
 Antonio Ospite <ao2@ao2.it> <ao2@amarulasolutions.com>
@@ -48,40 +48,42 @@ Arnaud Patard <arnaud.patard@rtp-net.org>
 Arnd Bergmann <arnd@arndb.de>
 Axel Dyks <xl@xlsigned.net>
 Axel Lin <axel.lin@gmail.com>
-Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
 Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
+Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
 Ben Gardner <bgardner@wabtec.com>
 Ben M Cahill <ben.m.cahill@intel.com>
 Björn Steinbrink <B.Steinbrink@gmx.de>
-Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
-Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com>
 Boris Brezillon <bbrezillon@kernel.org> <b.brezillon.dev@gmail.com>
 Boris Brezillon <bbrezillon@kernel.org> <b.brezillon@overkiz.com>
+Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@bootlin.com>
+Boris Brezillon <bbrezillon@kernel.org> <boris.brezillon@free-electrons.com>
 Brian Avery <b.avery@hp.com>
 Brian King <brking@us.ibm.com>
+Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
+Changbin Du <changbin.du@intel.com> <changbin.du@intel.com>
 Chao Yu <chao@kernel.org> <chao2.yu@samsung.com>
 Chao Yu <chao@kernel.org> <yuchao0@huawei.com>
-Christoph Hellwig <hch@lst.de>
 Christophe Ricard <christophe.ricard@gmail.com>
+Christoph Hellwig <hch@lst.de>
 Corey Minyard <minyard@acm.org>
 Damian Hobson-Garcia <dhobsong@igel.co.jp>
-Daniel Borkmann <daniel@iogearbox.net> <dborkman@redhat.com>
-Daniel Borkmann <daniel@iogearbox.net> <dborkmann@redhat.com>
+Daniel Borkmann <daniel@iogearbox.net> <danborkmann@googlemail.com>
 Daniel Borkmann <daniel@iogearbox.net> <danborkmann@iogearbox.net>
 Daniel Borkmann <daniel@iogearbox.net> <daniel.borkmann@tik.ee.ethz.ch>
-Daniel Borkmann <daniel@iogearbox.net> <danborkmann@googlemail.com>
+Daniel Borkmann <daniel@iogearbox.net> <dborkmann@redhat.com>
+Daniel Borkmann <daniel@iogearbox.net> <dborkman@redhat.com>
 Daniel Borkmann <daniel@iogearbox.net> <dxchgb@gmail.com>
 David Brownell <david-b@pacbell.net>
 David Woodhouse <dwmw2@shinybook.infradead.org>
-Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com>
-Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com>
 Dengcheng Zhu <dzhu@wavecomp.com> <dczhu@mips.com>
 Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@gmail.com>
+Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@imgtec.com>
+Dengcheng Zhu <dzhu@wavecomp.com> <dengcheng.zhu@mips.com>
 <dev.kurt@vandijck-laurijssen.be> <kurt.van.dijck@eia.be>
 Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
-Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com>
-Dmitry Safonov <0x7f454c46@gmail.com> <d.safonov@partner.samsung.com>
 Dmitry Safonov <0x7f454c46@gmail.com> <dima@arista.com>
+Dmitry Safonov <0x7f454c46@gmail.com> <d.safonov@partner.samsung.com>
+Dmitry Safonov <0x7f454c46@gmail.com> <dsafonov@virtuozzo.com>
 Domen Puncer <domen@coderock.org>
 Douglas Gilbert <dougg@torque.net>
 Ed L. Cashin <ecashin@coraid.com>
@@ -92,19 +94,22 @@ Felix Kuhling <fxkuehl@gmx.de>
 Felix Moeller <felix@derklecks.de>
 Filipe Lautert <filipe@icewall.org>
 Franck Bui-Huu <vagabon.xyz@gmail.com>
-Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com>
 Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com>
 Frank Rowand <frowand.list@gmail.com> <frank.rowand@sonymobile.com>
+Frank Rowand <frowand.list@gmail.com> <frowand@mvista.com>
 Frank Zago <fzago@systemfabricworks.com>
 Gao Xiang <xiang@kernel.org> <gaoxiang25@huawei.com>
 Gao Xiang <xiang@kernel.org> <hsiangkao@aol.com>
-Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
 Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@de.ibm.com>
+Gerald Schaefer <gerald.schaefer@linux.ibm.com> <gerald.schaefer@de.ibm.com>
 Gerald Schaefer <gerald.schaefer@linux.ibm.com> <geraldsc@linux.vnet.ibm.com>
 Greg Kroah-Hartman <greg@echidna.(none)>
 Greg Kroah-Hartman <gregkh@suse.de>
 Greg Kroah-Hartman <greg@kroah.com>
+Greg Kurz <groug@kaod.org> <gkurz@linux.vnet.ibm.com>
 Gregory CLEMENT <gregory.clement@bootlin.com> <gregory.clement@free-electrons.com>
+Gustavo Padovan <gustavo@las.ic.unicamp.br>
+Gustavo Padovan <padovan@profusion.mobi>
 Hanjun Guo <guohanjun@huawei.com> <hanjun.guo@linaro.org>
 Heiko Carstens <hca@linux.ibm.com> <h.carstens@de.ibm.com>
 Heiko Carstens <hca@linux.ibm.com> <heiko.carstens@de.ibm.com>
@@ -114,32 +119,32 @@ Henrik Rydberg <rydberg@bitmath.org>
 Herbert Xu <herbert@gondor.apana.org.au>
 Jacob Shin <Jacob.Shin@amd.com>
 Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@google.com>
-Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@motorola.com>
 Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk.kim@samsung.com>
+Jaegeuk Kim <jaegeuk@kernel.org> <jaegeuk@motorola.com>
 Jakub Kicinski <kuba@kernel.org> <jakub.kicinski@netronome.com>
 James Bottomley <jejb@mulgrave.(none)>
 James Bottomley <jejb@titanic.il.steeleye.com>
 James E Wilson <wilson@specifix.com>
-James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
 James Hogan <jhogan@kernel.org> <james@albanarts.com>
+James Hogan <jhogan@kernel.org> <james.hogan@imgtec.com>
 James Ketrenos <jketreno@io.(none)>
 Jan Glauber <jan.glauber@gmail.com> <jang@de.ibm.com>
 Jan Glauber <jan.glauber@gmail.com> <jang@linux.vnet.ibm.com>
 Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com>
 Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com>
 Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com>
-Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>
 <javier@osg.samsung.com> <javier.martinez@collabora.co.uk>
+Javi Merino <javi.merino@kernel.org> <javi.merino@arm.com>
 Jayachandran C <c.jayachandran@gmail.com> <jayachandranc@netlogicmicro.com>
 Jayachandran C <c.jayachandran@gmail.com> <jchandra@broadcom.com>
 Jayachandran C <c.jayachandran@gmail.com> <jchandra@digeo.com>
 Jayachandran C <c.jayachandran@gmail.com> <jnair@caviumnetworks.com>
-Jean Tourrilhes <jt@hpl.hp.com>
 <jean-philippe@linaro.org> <jean-philippe.brucker@arm.com>
+Jean Tourrilhes <jt@hpl.hp.com>
 Jeff Garzik <jgarzik@pretzel.yyz.us>
-Jeff Layton <jlayton@kernel.org> <jlayton@redhat.com>
 Jeff Layton <jlayton@kernel.org> <jlayton@poochiereds.net>
 Jeff Layton <jlayton@kernel.org> <jlayton@primarydata.com>
+Jeff Layton <jlayton@kernel.org> <jlayton@redhat.com>
 Jens Axboe <axboe@suse.de>
 Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
 Jiri Slaby <jirislaby@kernel.org> <jirislaby@gmail.com>
@@ -163,30 +168,30 @@ Julien Thierry <julien.thierry.kdev@gmail.com> <julien.thierry@arm.com>
 Kamil Konieczny <k.konieczny@samsung.com> <k.konieczny@partner.samsung.com>
 Kay Sievers <kay.sievers@vrfy.org>
 Kenneth W Chen <kenneth.w.chen@intel.com>
-Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com>
 Konstantin Khlebnikov <koct9i@gmail.com> <khlebnikov@yandex-team.ru>
+Konstantin Khlebnikov <koct9i@gmail.com> <k.khlebnikov@samsung.com>
 Koushik <raghavendra.koushik@neterion.com>
-Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
 Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski.k@gmail.com>
+Krzysztof Kozlowski <krzk@kernel.org> <k.kozlowski@samsung.com>
 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
-Leon Romanovsky <leon@kernel.org> <leon@leon.nu>
-Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com>
 Leonardo Bras <leobras.c@gmail.com> <leonardo@linux.ibm.com>
 Leonid I Ananiev <leonid.i.ananiev@intel.com>
+Leon Romanovsky <leon@kernel.org> <leon@leon.nu>
+Leon Romanovsky <leon@kernel.org> <leonro@mellanox.com>
 Linas Vepstas <linas@austin.ibm.com>
-Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de>
 Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@ascom.ch>
-Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
+Linus Lüssing <linus.luessing@c0d3.blue> <linus.luessing@web.de>
 Li Yang <leoyang.li@nxp.com> <leoli@freescale.com>
+Li Yang <leoyang.li@nxp.com> <leo@zh-kernel.org>
 Lukasz Luba <lukasz.luba@arm.com> <l.luba@partner.samsung.com>
 Maciej W. Rozycki <macro@mips.com> <macro@imgtec.com>
-Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com>
 Marcin Nowakowski <marcin.nowakowski@mips.com> <marcin.nowakowski@imgtec.com>
+Marc Zyngier <maz@kernel.org> <marc.zyngier@arm.com>
 Mark Brown <broonie@sirena.org.uk>
 Mark Yao <markyao0591@gmail.com> <mark.yao@rock-chips.com>
-Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
 Martin Kepplinger <martink@posteo.de> <martin.kepplinger@ginzinger.com>
 Martin Kepplinger <martink@posteo.de> <martin.kepplinger@puri.sm>
+Martin Kepplinger <martink@posteo.de> <martin.kepplinger@theobroma-systems.com>
 Mathieu Othacehe <m.othacehe@gmail.com>
 Matthew Wilcox <willy@infradead.org> <matthew.r.wilcox@intel.com>
 Matthew Wilcox <willy@infradead.org> <matthew@wil.cx>
@@ -196,17 +201,17 @@ Matthew Wilcox <willy@infradead.org> <willy@debian.org>
 Matthew Wilcox <willy@infradead.org> <willy@linux.intel.com>
 Matthew Wilcox <willy@infradead.org> <willy@parisc-linux.org>
 Matthieu CASTET <castet.matthieu@free.fr>
-Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@brturbo.com.br>
+Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting>
+Matt Ranostay <mranostay@gmail.com> Matthew Ranostay <mranostay@embeddedalley.com>
+Matt Ranostay <mranostay@gmail.com> <matt.ranostay@intel.com>
+Matt Redfearn <matt.redfearn@mips.com> <matt.redfearn@imgtec.com>
 Mauro Carvalho Chehab <mchehab@kernel.org> <maurochehab@gmail.com>
+Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@brturbo.com.br>
 Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@infradead.org>
+Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@osg.samsung.com>
 Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@redhat.com>
 Mauro Carvalho Chehab <mchehab@kernel.org> <m.chehab@samsung.com>
-Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@osg.samsung.com>
 Mauro Carvalho Chehab <mchehab@kernel.org> <mchehab@s-opensource.com>
-Matt Ranostay <mranostay@gmail.com> Matthew Ranostay <mranostay@embeddedalley.com>
-Matt Ranostay <mranostay@gmail.com> <matt.ranostay@intel.com>
-Matt Ranostay <matt.ranostay@konsulko.com> <matt@ranostay.consulting>
-Matt Redfearn <matt.redfearn@mips.com> <matt.redfearn@imgtec.com>
 Maxime Ripard <mripard@kernel.org> <maxime.ripard@bootlin.com>
 Maxime Ripard <mripard@kernel.org> <maxime.ripard@free-electrons.com>
 Mayuresh Janorkar <mayur@ti.com>
@@ -238,13 +243,13 @@ Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
 Patrick Mochel <mochel@digitalimplant.org>
 Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com>
 Paul Burton <paulburton@kernel.org> <paul.burton@mips.com>
+Paul E. McKenney <paulmck@kernel.org> <paul.mckenney@linaro.org>
 Paul E. McKenney <paulmck@kernel.org> <paulmck@linux.ibm.com>
 Paul E. McKenney <paulmck@kernel.org> <paulmck@linux.vnet.ibm.com>
-Paul E. McKenney <paulmck@kernel.org> <paul.mckenney@linaro.org>
 Paul E. McKenney <paulmck@kernel.org> <paulmck@us.ibm.com>
 Peter A Jonsson <pj@ludd.ltu.se>
-Peter Oruba <peter@oruba.de>
 Peter Oruba <peter.oruba@amd.com>
+Peter Oruba <peter@oruba.de>
 Pratyush Anand <pratyush.anand@gmail.com> <pratyush.anand@st.com>
 Praveen BP <praveenbp@ti.com>
 Punit Agrawal <punitagrawal@gmail.com> <punit.agrawal@arm.com>
@@ -257,23 +262,23 @@ Ralf Baechle <ralf@linux-mips.org>
 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
 Randy Dunlap <rdunlap@infradead.org> <rdunlap@xenotime.net>
 Rémi Denis-Courmont <rdenis@simphalempin.com>
-Ricardo Ribalda <ribalda@kernel.org> <ricardo.ribalda@gmail.com>
 Ricardo Ribalda <ribalda@kernel.org> <ricardo@ribalda.com>
 Ricardo Ribalda <ribalda@kernel.org> Ricardo Ribalda Delgado <ribalda@kernel.org>
+Ricardo Ribalda <ribalda@kernel.org> <ricardo.ribalda@gmail.com>
 Ross Zwisler <zwisler@kernel.org> <ross.zwisler@linux.intel.com>
 Rudolf Marek <R.Marek@sh.cvut.cz>
 Rui Saraiva <rmps@joel.ist.utl.pt>
 Sachin P Sant <ssant@in.ibm.com>
-Sarangdhar Joshi <spjoshi@codeaurora.org>
+Sakari Ailus <sakari.ailus@linux.intel.com> <sakari.ailus@iki.fi>
 Sam Ravnborg <sam@mars.ravnborg.org>
-Santosh Shilimkar <ssantosh@kernel.org>
 Santosh Shilimkar <santosh.shilimkar@oracle.org>
+Santosh Shilimkar <ssantosh@kernel.org>
+Sarangdhar Joshi <spjoshi@codeaurora.org>
 Sascha Hauer <s.hauer@pengutronix.de>
 S.ÇaÄŸlar Onur <caglar@pardus.org.tr>
-Sakari Ailus <sakari.ailus@linux.intel.com> <sakari.ailus@iki.fi>
 Sean Nyekjaer <sean@geanix.com> <sean.nyekjaer@prevas.dk>
-Sebastian Reichel <sre@kernel.org> <sre@debian.org>
 Sebastian Reichel <sre@kernel.org> <sebastian.reichel@collabora.co.uk>
+Sebastian Reichel <sre@kernel.org> <sre@debian.org>
 Sedat Dilek <sedat.dilek@gmail.com> <sedat.dilek@credativ.de>
 Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
 Shuah Khan <shuah@kernel.org> <shuahkhan@gmail.com>
@@ -284,18 +289,21 @@ Simon Arlott <simon@octiron.net> <simon@fire.lp0.eu>
 Simon Kelley <simon@thekelleys.org.uk>
 Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
 Stephen Hemminger <shemminger@osdl.org>
+Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>
+Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
 Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
 Subhash Jadavani <subhashj@codeaurora.org>
 Sudeep Holla <sudeep.holla@arm.com> Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
 Sumit Semwal <sumit.semwal@ti.com>
+Takashi YOSHII <takashi.yoshii.zj@renesas.com>
 Tejun Heo <htejun@gmail.com>
 Thomas Graf <tgraf@suug.ch>
 Thomas Pedersen <twp@codeaurora.org>
 Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com>
 Todor Tomov <todor.too@gmail.com> <todor.tomov@linaro.org>
 Tony Luck <tony.luck@intel.com>
-TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn>
 TripleX Chung <xxx.phy@gmail.com> <triplex@zh-kernel.org>
+TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn>
 Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
 Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
 Uwe Kleine-König <ukl@pengutronix.de>
@@ -304,22 +312,16 @@ Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
 Vinod Koul <vkoul@kernel.org> <vinod.koul@intel.com>
 Vinod Koul <vkoul@kernel.org> <vinod.koul@linux.intel.com>
 Vinod Koul <vkoul@kernel.org> <vkoul@infradead.org>
+Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
 Viresh Kumar <vireshk@kernel.org> <viresh.kumar@st.com>
 Viresh Kumar <vireshk@kernel.org> <viresh.linux@gmail.com>
-Viresh Kumar <vireshk@kernel.org> <viresh.kumar2@arm.com>
 Vivien Didelot <vivien.didelot@gmail.com> <vivien.didelot@savoirfairelinux.com>
 Vlad Dogaru <ddvlad@gmail.com> <vlad.dogaru@intel.com>
-Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
 Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@parallels.com>
-Takashi YOSHII <takashi.yoshii.zj@renesas.com>
+Vladimir Davydov <vdavydov.dev@gmail.com> <vdavydov@virtuozzo.com>
+WeiXiong Liao <gmpy.liaowx@gmail.com> <liaoweixiong@allwinnertech.com>
 Will Deacon <will@kernel.org> <will.deacon@arm.com>
-Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de>
 Wolfram Sang <wsa@kernel.org> <w.sang@pengutronix.de>
+Wolfram Sang <wsa@kernel.org> <wsa@the-dreams.de>
 Yakir Yang <kuankuan.y@gmail.com> <ykk@rock-chips.com>
 Yusuke Goda <goda.yusuke@renesas.com>
-Gustavo Padovan <gustavo@las.ic.unicamp.br>
-Gustavo Padovan <padovan@profusion.mobi>
-Changbin Du <changbin.du@intel.com> <changbin.du@intel.com>
-Changbin Du <changbin.du@intel.com> <changbin.du@gmail.com>
-Steve Wise <larrystevenwise@gmail.com> <swise@chelsio.com>
-Steve Wise <larrystevenwise@gmail.com> <swise@opengridcomputing.com>
index ba9988d..140e4ce 100644 (file)
@@ -80,6 +80,10 @@ The possible values in this file are:
        - The processor is not vulnerable.
      * - KVM: Mitigation: Split huge pages
        - Software changes mitigate this issue.
+     * - KVM: Mitigation: VMX unsupported
+       - KVM is not vulnerable because Virtual Machine Extensions (VMX) is not supported.
+     * - KVM: Mitigation: VMX disabled
+       - KVM is not vulnerable because Virtual Machine Extensions (VMX) is disabled.
      * - KVM: Vulnerable
        - The processor is vulnerable, but no mitigation enabled
 
index 9db9249..7adef96 100644 (file)
@@ -54,10 +54,13 @@ registered (see `below <status_attr_>`_).
 Operation Modes
 ===============
 
-``intel_pstate`` can operate in three different modes: in the active mode with
-or without hardware-managed P-states support and in the passive mode.  Which of
-them will be in effect depends on what kernel command line options are used and
-on the capabilities of the processor.
+``intel_pstate`` can operate in two different modes, active or passive.  In the
+active mode, it uses its own internal performance scaling governor algorithm or
+allows the hardware to do preformance scaling by itself, while in the passive
+mode it responds to requests made by a generic ``CPUFreq`` governor implementing
+a certain performance scaling algorithm.  Which of them will be in effect
+depends on what kernel command line options are used and on the capabilities of
+the processor.
 
 Active Mode
 -----------
@@ -194,10 +197,11 @@ This is the default operation mode of ``intel_pstate`` for processors without
 hardware-managed P-states (HWP) support.  It is always used if the
 ``intel_pstate=passive`` argument is passed to the kernel in the command line
 regardless of whether or not the given processor supports HWP.  [Note that the
-``intel_pstate=no_hwp`` setting implies ``intel_pstate=passive`` if it is used
-without ``intel_pstate=active``.]  Like in the active mode without HWP support,
-in this mode ``intel_pstate`` may refuse to work with processors that are not
-recognized by it.
+``intel_pstate=no_hwp`` setting causes the driver to start in the passive mode
+if it is not combined with ``intel_pstate=active``.]  Like in the active mode
+without HWP support, in this mode ``intel_pstate`` may refuse to work with
+processors that are not recognized by it if HWP is prevented from being enabled
+through the kernel command line.
 
 If the driver works in this mode, the ``scaling_driver`` policy attribute in
 ``sysfs`` for all ``CPUFreq`` policies contains the string "intel_cpufreq".
@@ -318,10 +322,9 @@ manuals need to be consulted to get to it too.
 
 For this reason, there is a list of supported processors in ``intel_pstate`` and
 the driver initialization will fail if the detected processor is not in that
-list, unless it supports the `HWP feature <Active Mode_>`_.  [The interface to
-obtain all of the information listed above is the same for all of the processors
-supporting the HWP feature, which is why they all are supported by
-``intel_pstate``.]
+list, unless it supports the HWP feature.  [The interface to obtain all of the
+information listed above is the same for all of the processors supporting the
+HWP feature, which is why ``intel_pstate`` works with all of them.]
 
 
 User Space Interface in ``sysfs``
@@ -425,22 +428,16 @@ argument is passed to the kernel in the command line.
        as well as the per-policy ones) are then reset to their default
        values, possibly depending on the target operation mode.]
 
-       That only is supported in some configurations, though (for example, if
-       the `HWP feature is enabled in the processor <Active Mode With HWP_>`_,
-       the operation mode of the driver cannot be changed), and if it is not
-       supported in the current configuration, writes to this attribute will
-       fail with an appropriate error.
-
 ``energy_efficiency``
-       This attribute is only present on platforms, which have CPUs matching
-       Kaby Lake or Coffee Lake desktop CPU model. By default
-       energy efficiency optimizations are disabled on these CPU models in HWP
-       mode by this driver. Enabling energy efficiency may limit maximum
-       operating frequency in both HWP and non HWP mode. In non HWP mode,
-       optimizations are done only in the turbo frequency range. In HWP mode,
-       optimizations are done in the entire frequency range. Setting this
-       attribute to "1" enables energy efficiency optimizations and setting
-       to "0" disables energy efficiency optimizations.
+       This attribute is only present on platforms with CPUs matching the Kaby
+       Lake or Coffee Lake desktop CPU model. By default, energy-efficiency
+       optimizations are disabled on these CPU models if HWP is enabled.
+       Enabling energy-efficiency optimizations may limit maximum operating
+       frequency with or without the HWP feature.  With HWP enabled, the
+       optimizations are done only in the turbo frequency range.  Without it,
+       they are done in the entire available frequency range.  Setting this
+       attribute to "1" enables the energy-efficiency optimizations and setting
+       to "0" disables them.
 
 Interpretation of Policy Attributes
 -----------------------------------
@@ -484,8 +481,8 @@ Next, the following policy attributes have special meaning if
        policy for the time interval between the last two invocations of the
        driver's utilization update callback by the CPU scheduler for that CPU.
 
-One more policy attribute is present if the `HWP feature is enabled in the
-processor <Active Mode With HWP_>`_:
+One more policy attribute is present if the HWP feature is enabled in the
+processor:
 
 ``base_frequency``
        Shows the base frequency of the CPU. Any frequency above this will be
@@ -526,11 +523,11 @@ on the following rules, regardless of the current operation mode of the driver:
 
  3. The global and per-policy limits can be set independently.
 
-If the `HWP feature is enabled in the processor <Active Mode With HWP_>`_, the
-resulting effective values are written into its registers whenever the limits
-change in order to request its internal P-state selection logic to always set
-P-states within these limits.  Otherwise, the limits are taken into account by
-scaling governors (in the `passive mode <Passive Mode_>`_) and by the driver
+In the `active mode with the HWP feature enabled <Active Mode With HWP_>`_, the
+resulting effective values are written into hardware registers whenever the
+limits change in order to request its internal P-state selection logic to always
+set P-states within these limits.  Otherwise, the limits are taken into account
+by scaling governors (in the `passive mode <Passive Mode_>`_) and by the driver
 every time before setting a new P-state for a CPU.
 
 Additionally, if the ``intel_pstate=per_cpu_perf_limits`` command line argument
@@ -541,12 +538,11 @@ at all and the only way to set the limits is by using the policy attributes.
 Energy vs Performance Hints
 ---------------------------
 
-If ``intel_pstate`` works in the `active mode with the HWP feature enabled
-<Active Mode With HWP_>`_ in the processor, additional attributes are present
-in every ``CPUFreq`` policy directory in ``sysfs``.  They are intended to allow
-user space to help ``intel_pstate`` to adjust the processor's internal P-state
-selection logic by focusing it on performance or on energy-efficiency, or
-somewhere between the two extremes:
+If the hardware-managed P-states (HWP) is enabled in the processor, additional
+attributes, intended to allow user space to help ``intel_pstate`` to adjust the
+processor's internal P-state selection logic by focusing it on performance or on
+energy-efficiency, or somewhere between the two extremes, are present in every
+``CPUFreq`` policy directory in ``sysfs``.  They are :
 
 ``energy_performance_preference``
        Current value of the energy vs performance hint for the given policy
@@ -650,12 +646,14 @@ of them have to be prepended with the ``intel_pstate=`` prefix.
        Do not register ``intel_pstate`` as the scaling driver even if the
        processor is supported by it.
 
+``active``
+       Register ``intel_pstate`` in the `active mode <Active Mode_>`_ to start
+       with.
+
 ``passive``
        Register ``intel_pstate`` in the `passive mode <Passive Mode_>`_ to
        start with.
 
-       This option implies the ``no_hwp`` one described below.
-
 ``force``
        Register ``intel_pstate`` as the scaling driver instead of
        ``acpi-cpufreq`` even if the latter is preferred on the given system.
@@ -670,13 +668,12 @@ of them have to be prepended with the ``intel_pstate=`` prefix.
        driver is used instead of ``acpi-cpufreq``.
 
 ``no_hwp``
-       Do not enable the `hardware-managed P-states (HWP) feature
-       <Active Mode With HWP_>`_ even if it is supported by the processor.
+       Do not enable the hardware-managed P-states (HWP) feature even if it is
+       supported by the processor.
 
 ``hwp_only``
        Register ``intel_pstate`` as the scaling driver only if the
-       `hardware-managed P-states (HWP) feature <Active Mode With HWP_>`_ is
-       supported by the processor.
+       hardware-managed P-states (HWP) feature is supported by the processor.
 
 ``support_acpi_ppc``
        Take ACPI ``_PPC`` performance limits into account.
index d46429b..7df2465 100644 (file)
@@ -36,6 +36,12 @@ Two sets of Questions and Answers (Q&A) are maintained.
    bpf_devel_QA
 
 
+Helper functions
+================
+
+* `bpf-helpers(7)`_ maintains a list of helpers available to eBPF programs.
+
+
 Program types
 =============
 
@@ -79,4 +85,5 @@ Other
 .. _networking-filter: ../networking/filter.rst
 .. _man-pages: https://www.kernel.org/doc/man-pages/
 .. _bpf(2): https://man7.org/linux/man-pages/man2/bpf.2.html
+.. _bpf-helpers(7): https://man7.org/linux/man-pages/man7/bpf-helpers.7.html
 .. _BPF and XDP Reference Guide: https://docs.cilium.io/en/latest/bpf/
index 192ded4..f0daf99 100644 (file)
@@ -67,9 +67,9 @@ patternProperties:
       compatible:
         items:
           - enum:
-            - arm,integrator-ap-syscon
-            - arm,integrator-cp-syscon
-            - arm,integrator-sp-syscon
+              - arm,integrator-ap-syscon
+              - arm,integrator-cp-syscon
+              - arm,integrator-sp-syscon
           - const: syscon
       reg:
         maxItems: 1
index d6e85d1..1d0b4e2 100644 (file)
@@ -55,20 +55,20 @@ properties:
       compatible:
         oneOf:
           - items:
-            - const: arm,realview-eb-soc
-            - const: simple-bus
+              - const: arm,realview-eb-soc
+              - const: simple-bus
           - items:
-            - const: arm,realview-pb1176-soc
-            - const: simple-bus
+              - const: arm,realview-pb1176-soc
+              - const: simple-bus
           - items:
-            - const: arm,realview-pb11mp-soc
-            - const: simple-bus
+              - const: arm,realview-pb11mp-soc
+              - const: simple-bus
           - items:
-            - const: arm,realview-pba8-soc
-            - const: simple-bus
+              - const: arm,realview-pba8-soc
+              - const: simple-bus
           - items:
-            - const: arm,realview-pbx-soc
-            - const: simple-bus
+              - const: arm,realview-pbx-soc
+              - const: simple-bus
 
     patternProperties:
       "^.*syscon@[0-9a-f]+$":
@@ -79,35 +79,35 @@ properties:
           compatible:
             oneOf:
               - items:
-                - const: arm,realview-eb11mp-revb-syscon
-                - const: arm,realview-eb-syscon
-                - const: syscon
-                - const: simple-mfd
+                  - const: arm,realview-eb11mp-revb-syscon
+                  - const: arm,realview-eb-syscon
+                  - const: syscon
+                  - const: simple-mfd
               - items:
-                - const: arm,realview-eb11mp-revc-syscon
-                - const: arm,realview-eb-syscon
-                - const: syscon
-                - const: simple-mfd
+                  - const: arm,realview-eb11mp-revc-syscon
+                  - const: arm,realview-eb-syscon
+                  - const: syscon
+                  - const: simple-mfd
               - items:
-                - const: arm,realview-eb-syscon
-                - const: syscon
-                - const: simple-mfd
+                  - const: arm,realview-eb-syscon
+                  - const: syscon
+                  - const: simple-mfd
               - items:
-                - const: arm,realview-pb1176-syscon
-                - const: syscon
-                - const: simple-mfd
+                  - const: arm,realview-pb1176-syscon
+                  - const: syscon
+                  - const: simple-mfd
               - items:
-                - const: arm,realview-pb11mp-syscon
-                - const: syscon
-                - const: simple-mfd
+                  - const: arm,realview-pb11mp-syscon
+                  - const: syscon
+                  - const: simple-mfd
               - items:
-                - const: arm,realview-pba8-syscon
-                - const: syscon
-                - const: simple-mfd
+                  - const: arm,realview-pba8-syscon
+                  - const: syscon
+                  - const: simple-mfd
               - items:
-                - const: arm,realview-pbx-syscon
-                - const: syscon
-                - const: simple-mfd
+                  - const: arm,realview-pbx-syscon
+                  - const: syscon
+                  - const: simple-mfd
 
         required:
           - compatible
index a3420c8..26829a8 100644 (file)
@@ -165,10 +165,10 @@ patternProperties:
       compatible:
         oneOf:
           - items:
-            - enum:
-              - arm,vexpress,v2m-p1
-              - arm,vexpress,v2p-p1
-            - const: simple-bus
+              - enum:
+                  - arm,vexpress,v2m-p1
+                  - arm,vexpress,v2p-p1
+              - const: simple-bus
           - const: simple-bus
       motherboard:
         type: object
@@ -186,8 +186,8 @@ patternProperties:
           compatible:
             items:
               - enum:
-                - arm,vexpress,v2m-p1
-                - arm,vexpress,v2p-p1
+                  - arm,vexpress,v2m-p1
+                  - arm,vexpress,v2p-p1
               - const: simple-bus
           arm,v2m-memory-map:
             description: This describes the memory map type.
index b5ef266..497600a 100644 (file)
@@ -15,7 +15,7 @@ properties:
   compatible:
     items:
       - enum:
-        - brcm,bcm28155-ap
+          - brcm,bcm28155-ap
       - const: brcm,bcm11351
 
 ...
index aafbd6a..e0ee931 100644 (file)
@@ -15,7 +15,7 @@ properties:
   compatible:
     items:
       - enum:
-        - brcm,bcm21664-garnet
+          - brcm,bcm21664-garnet
       - const: brcm,bcm21664
 
 ...
index c4b4efd..40d12ea 100644 (file)
@@ -15,7 +15,7 @@ properties:
   compatible:
     items:
       - enum:
-        - brcm,bcm23550-sparrow
+          - brcm,bcm23550-sparrow
       - const: brcm,bcm23550
 
 ...
index fe111e7..9ba7b16 100644 (file)
@@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Broadcom Cygnus device tree bindings
 
 maintainers:
-   - Ray Jui <rjui@broadcom.com>
-   - Scott Branden <sbranden@broadcom.com>
+  - Ray Jui <rjui@broadcom.com>
+  - Scott Branden <sbranden@broadcom.com>
 
 properties:
   $nodename:
@@ -16,14 +16,14 @@ properties:
   compatible:
     items:
       - enum:
-        - brcm,bcm11300
-        - brcm,bcm11320
-        - brcm,bcm11350
-        - brcm,bcm11360
-        - brcm,bcm58300
-        - brcm,bcm58302
-        - brcm,bcm58303
-        - brcm,bcm58305
+          - brcm,bcm11300
+          - brcm,bcm11320
+          - brcm,bcm11350
+          - brcm,bcm11360
+          - brcm,bcm58300
+          - brcm,bcm58302
+          - brcm,bcm58303
+          - brcm,bcm58305
       - const: brcm,cygnus
 
 ...
index 1158f49..ae614b6 100644 (file)
@@ -21,7 +21,7 @@ properties:
   compatible:
     items:
       - enum:
-        - ubnt,unifi-switch8
+          - ubnt,unifi-switch8
       - const: brcm,bcm53342
       - const: brcm,hr2
 
index 2451704..0749adf 100644 (file)
@@ -16,8 +16,8 @@ properties:
   compatible:
     items:
       - enum:
-        - brcm,ns2-svk
-        - brcm,ns2-xmc
+          - brcm,ns2-svk
+          - brcm,ns2-xmc
       - const: brcm,ns2
 
 ...
index fe364ce..8c2cacb 100644 (file)
@@ -24,13 +24,13 @@ properties:
   compatible:
     items:
       - enum:
-        - brcm,bcm58522
-        - brcm,bcm58525
-        - brcm,bcm58535
-        - brcm,bcm58622
-        - brcm,bcm58623
-        - brcm,bcm58625
-        - brcm,bcm88312
+          - brcm,bcm58522
+          - brcm,bcm58525
+          - brcm,bcm58535
+          - brcm,bcm58622
+          - brcm,bcm58623
+          - brcm,bcm58625
+          - brcm,bcm88312
       - const: brcm,nsp
 
 ...
index 4ad2b21..c13cb96 100644 (file)
@@ -16,9 +16,9 @@ properties:
   compatible:
     items:
       - enum:
-        - brcm,bcm958742k
-        - brcm,bcm958742t
-        - brcm,bcm958802a802x
+          - brcm,bcm958742k
+          - brcm,bcm958742t
+          - brcm,bcm958802a802x
       - const: brcm,stingray
 
 ...
index c5b6f31..ccdf9f9 100644 (file)
@@ -15,8 +15,8 @@ properties:
   compatible:
     items:
       - enum:
-        - brcm,vulcan-eval
-        - cavium,thunderx2-cn9900
+          - brcm,vulcan-eval
+          - cavium,thunderx2-cn9900
       - const: brcm,vulcan-soc
 
 ...
index 17df5cd..e42ff69 100644 (file)
@@ -82,12 +82,12 @@ properties:
   compatible:
     oneOf:
       - items:
-        - const: arm,coresight-cti
-        - const: arm,primecell
+          - const: arm,coresight-cti
+          - const: arm,primecell
       - items:
-        - const: arm,coresight-cti-v8-arch
-        - const: arm,coresight-cti
-        - const: arm,primecell
+          - const: arm,coresight-cti-v8-arch
+          - const: arm,coresight-cti
+          - const: arm,primecell
 
   reg:
     maxItems: 1
@@ -191,16 +191,16 @@ patternProperties:
 
     anyOf:
       - required:
-        - arm,trig-in-sigs
+          - arm,trig-in-sigs
       - required:
-        - arm,trig-out-sigs
+          - arm,trig-out-sigs
     oneOf:
       - required:
-        - arm,trig-conn-name
+          - arm,trig-conn-name
       - required:
-        - cpu
+          - cpu
       - required:
-        - arm,cs-dev-assoc
+          - arm,cs-dev-assoc
     required:
       - reg
 
index 40f692c..1222bf1 100644 (file)
@@ -330,8 +330,8 @@ if:
     - enable-method
 
 then:
-   required:
-     - secondary-boot-reg
+  required:
+    - secondary-boot-reg
 
 required:
   - device_type
index f63895c..6da9d73 100644 (file)
@@ -273,8 +273,8 @@ properties:
               - fsl,imx6ull-14x14-evk     # i.MX6 UltraLiteLite 14x14 EVK Board
               - kontron,imx6ull-n6411-som # Kontron N6411 SOM
               - myir,imx6ull-mys-6ulx-eval # MYiR Tech iMX6ULL Evaluation Board
-              - toradex,colibri-imx6ull-eval            # Colibri iMX6ULL Module on Colibri Evaluation Board
-              - toradex,colibri-imx6ull-wifi-eval       # Colibri iMX6ULL Wi-Fi / Bluetooth Module on Colibri Evaluation Board
+              - toradex,colibri-imx6ull-eval      # Colibri iMX6ULL Module on Colibri Eval Board
+              - toradex,colibri-imx6ull-wifi-eval # Colibri iMX6ULL Wi-Fi / BT Module on Colibri Eval Board
           - const: fsl,imx6ull
 
       - description: Kontron N6411 S Board
@@ -312,9 +312,12 @@ properties:
               - toradex,colibri-imx7d                   # Colibri iMX7 Dual Module
               - toradex,colibri-imx7d-aster             # Colibri iMX7 Dual Module on Aster Carrier Board
               - toradex,colibri-imx7d-emmc              # Colibri iMX7 Dual 1GB (eMMC) Module
-              - toradex,colibri-imx7d-emmc-aster        # Colibri iMX7 Dual 1GB (eMMC) Module on Aster Carrier Board
-              - toradex,colibri-imx7d-emmc-eval-v3      # Colibri iMX7 Dual 1GB (eMMC) Module on Colibri Evaluation Board V3
-              - toradex,colibri-imx7d-eval-v3           # Colibri iMX7 Dual Module on Colibri Evaluation Board V3
+              - toradex,colibri-imx7d-emmc-aster        # Colibri iMX7 Dual 1GB (eMMC) Module on
+                                                        #  Aster Carrier Board
+              - toradex,colibri-imx7d-emmc-eval-v3      # Colibri iMX7 Dual 1GB (eMMC) Module on
+                                                        #  Colibri Evaluation Board V3
+              - toradex,colibri-imx7d-eval-v3           # Colibri iMX7 Dual Module on
+                                                        #  Colibri Evaluation Board V3
               - tq,imx7d-mba7             # i.MX7D TQ MBa7 with TQMa7D SoM
               - zii,imx7d-rmu2            # ZII RMU2 Board
               - zii,imx7d-rpu2            # ZII RPU2 Board
index 4d92578..06a7b05 100644 (file)
@@ -14,6 +14,6 @@ properties:
   compatible:
     items:
       - enum:
-        - intel,keembay-evm
+          - intel,keembay-evm
       - const: intel,keembay
 ...
index e271c46..1af3017 100644 (file)
@@ -17,22 +17,22 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - mediatek,mt2701-pericfg
-          - mediatek,mt2712-pericfg
-          - mediatek,mt6765-pericfg
-          - mediatek,mt7622-pericfg
-          - mediatek,mt7629-pericfg
-          - mediatek,mt8135-pericfg
-          - mediatek,mt8173-pericfg
-          - mediatek,mt8183-pericfg
-          - mediatek,mt8516-pericfg
-        - const: syscon
+          - enum:
+              - mediatek,mt2701-pericfg
+              - mediatek,mt2712-pericfg
+              - mediatek,mt6765-pericfg
+              - mediatek,mt7622-pericfg
+              - mediatek,mt7629-pericfg
+              - mediatek,mt8135-pericfg
+              - mediatek,mt8173-pericfg
+              - mediatek,mt8183-pericfg
+              - mediatek,mt8516-pericfg
+          - const: syscon
       - items:
-        # Special case for mt7623 for backward compatibility
-        - const: mediatek,mt7623-pericfg
-        - const: mediatek,mt2701-pericfg
-        - const: syscon
+          # Special case for mt7623 for backward compatibility
+          - const: mediatek,mt7623-pericfg
+          - const: mediatek,mt2701-pericfg
+          - const: syscon
 
   reg:
     maxItems: 1
index 68b0131..37ba333 100644 (file)
@@ -19,7 +19,7 @@ description: |
   reported to the APB terminator (APB Errors Handler Block).
 
 allOf:
- - $ref: /schemas/simple-bus.yaml#
 - $ref: /schemas/simple-bus.yaml#
 
 properties:
   compatible:
index 29e1aae..0bee469 100644 (file)
@@ -23,7 +23,7 @@ description: |
   accessible by means of the Baikal-T1 System Controller.
 
 allOf:
- - $ref: /schemas/simple-bus.yaml#
 - $ref: /schemas/simple-bus.yaml#
 
 properties:
   compatible:
index 3d4e168..28c6461 100644 (file)
@@ -95,10 +95,10 @@ allOf:
       # Devices without builtin crystal
       properties:
         clock-names:
-            minItems: 1
-            maxItems: 2
-            items:
-              enum: [ xin, clkin ]
+          minItems: 1
+          maxItems: 2
+          items:
+            enum: [ xin, clkin ]
         clocks:
           minItems: 1
           maxItems: 2
index a952d58..5dd7ea8 100644 (file)
@@ -47,12 +47,12 @@ properties:
   compatible:
     items:
       - enum:
-        - ingenic,jz4740-cgu
-        - ingenic,jz4725b-cgu
-        - ingenic,jz4770-cgu
-        - ingenic,jz4780-cgu
-        - ingenic,x1000-cgu
-        - ingenic,x1830-cgu
+          - ingenic,jz4740-cgu
+          - ingenic,jz4725b-cgu
+          - ingenic,jz4770-cgu
+          - ingenic,jz4780-cgu
+          - ingenic,x1000-cgu
+          - ingenic,x1830-cgu
       - const: simple-mfd
     minItems: 1
 
@@ -68,8 +68,8 @@ properties:
     items:
       - const: ext
       - enum:
-        - rtc
-        - osc32k # Different name, same clock
+          - rtc
+          - osc32k # Different name, same clock
 
   assigned-clocks:
     minItems: 1
index 1b16a86..af32dee 100644 (file)
@@ -65,7 +65,7 @@ properties:
 
   protected-clocks:
     description:
-       Protected clock specifier list as per common clock binding
+      Protected clock specifier list as per common clock binding
 
   vdd-gfx-supply:
     description:
index b83f413..9185d10 100644 (file)
@@ -19,15 +19,15 @@ description:
 properties:
   compatible:
     oneOf:
-      - const: renesas,r8a73a4-cpg-clocks # R-Mobile APE6
-      - const: renesas,r8a7740-cpg-clocks # R-Mobile A1
-      - const: renesas,r8a7778-cpg-clocks # R-Car M1
-      - const: renesas,r8a7779-cpg-clocks # R-Car H1
+      - const: renesas,r8a73a4-cpg-clocks     # R-Mobile APE6
+      - const: renesas,r8a7740-cpg-clocks     # R-Mobile A1
+      - const: renesas,r8a7778-cpg-clocks     # R-Car M1
+      - const: renesas,r8a7779-cpg-clocks     # R-Car H1
       - items:
-        - enum:
-            - renesas,r7s72100-cpg-clocks # RZ/A1H
-        - const: renesas,rz-cpg-clocks    # RZ/A1
-      - const: renesas,sh73a0-cpg-clocks  # SH-Mobile AG5
+          - enum:
+              - renesas,r7s72100-cpg-clocks   # RZ/A1H
+          - const: renesas,rz-cpg-clocks      # RZ/A1
+      - const: renesas,sh73a0-cpg-clocks      # SH-Mobile AG5
 
   reg:
     maxItems: 1
index 2981387..c6d0915 100644 (file)
@@ -16,7 +16,7 @@ properties:
   "#clock-cells":
     const: 1
 
-  compatible :
+  compatible:
     enum:
       - sprd,sc9863a-ap-clk
       - sprd,sc9863a-aon-clk
index 52b3cda..f54b4e4 100644 (file)
@@ -32,8 +32,7 @@ properties:
       - const: hdmi
 
   ddc:
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
     description: >
       Phandle of the I2C controller used for DDC EDID probing
 
index 2c4c34e..04099f5 100644 (file)
@@ -162,14 +162,13 @@ required:
 additionalProperties: false
 
 examples:
- - |
+  - |
+    #include <dt-bindings/clock/imx8mq-clock.h>
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/reset/imx8mq-reset.h>
 
-   #include <dt-bindings/clock/imx8mq-clock.h>
-   #include <dt-bindings/gpio/gpio.h>
-   #include <dt-bindings/interrupt-controller/arm-gic.h>
-   #include <dt-bindings/reset/imx8mq-reset.h>
-
-   mipi_dsi: mipi_dsi@30a00000 {
+    mipi_dsi: mipi_dsi@30a00000 {
               #address-cells = <1>;
               #size-cells = <0>;
               compatible = "fsl,imx8mq-nwl-dsi";
@@ -224,4 +223,4 @@ examples:
                            };
                     };
               };
-      };
+    };
index 98c7330..baaf2a2 100644 (file)
@@ -119,17 +119,17 @@ then:
         # The LVDS encoder can use the EXTAL or DU_DOTCLKINx clocks.
         # These clocks are optional.
         - enum:
-          - extal
-          - dclkin.0
-          - dclkin.1
+            - extal
+            - dclkin.0
+            - dclkin.1
         - enum:
-          - extal
-          - dclkin.0
-          - dclkin.1
+            - extal
+            - dclkin.0
+            - dclkin.1
         - enum:
-          - extal
-          - dclkin.0
-          - dclkin.1
+            - extal
+            - dclkin.0
+            - dclkin.1
 
   required:
     - clock-names
index 0880cbf..3ddb35f 100644 (file)
@@ -18,16 +18,16 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - ti,ths8134a
-          - ti,ths8134b
-        - const: ti,ths8134
+          - enum:
+              - ti,ths8134a
+              - ti,ths8134b
+          - const: ti,ths8134
       - enum:
-        - adi,adv7123
-        - dumb-vga-dac
-        - ti,opa362
-        - ti,ths8134
-        - ti,ths8135
+          - adi,adv7123
+          - dumb-vga-dac
+          - ti,opa362
+          - ti,ths8134
+          - ti,ths8135
 
   ports:
     type: object
index 85b71b1..a02039e 100644 (file)
@@ -55,11 +55,11 @@ patternProperties:
       clock-master:
         type: boolean
         description:
-           Should be enabled if the host is being used in conjunction with
-           another DSI host to drive the same peripheral. Hardware supporting
-           such a configuration generally requires the data on both the busses
-           to be driven by the same clock. Only the DSI host instance
-           controlling this clock should contain this property.
+          Should be enabled if the host is being used in conjunction with
+          another DSI host to drive the same peripheral. Hardware supporting
+          such a configuration generally requires the data on both the busses
+          to be driven by the same clock. Only the DSI host instance
+          controlling this clock should contain this property.
 
       enforce-video-mode:
         type: boolean
index 66e93e5..aecff34 100644 (file)
@@ -21,9 +21,9 @@ properties:
     items:
       - enum:
           # Waveshare 3.5" 320x480 Color TFT LCD
-        - waveshare,rpi-lcd-35
+          - waveshare,rpi-lcd-35
           # Ozzmaker 3.5" 320x480 Color TFT LCD
-        - ozzmaker,piscreen
+          - ozzmaker,piscreen
       - const: ilitek,ili9486
 
   spi-max-frequency:
index 5bfc33e..12064a8 100644 (file)
@@ -13,11 +13,11 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4725b-ipu
-        - ingenic,jz4760-ipu
+          - ingenic,jz4725b-ipu
+          - ingenic,jz4760-ipu
       - items:
-        - const: ingenic,jz4770-ipu
-        - const: ingenic,jz4760-ipu
+          - const: ingenic,jz4770-ipu
+          - const: ingenic,jz4760-ipu
 
   reg:
     maxItems: 1
index d56db18..768050f 100644 (file)
@@ -58,11 +58,11 @@ properties:
       - port@0
 
 required:
-    - compatible
-    - reg
-    - interrupts
-    - clocks
-    - clock-names
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - clock-names
 
 if:
   properties:
index 0b8736a..53056dd 100644 (file)
@@ -38,10 +38,10 @@ properties:
 
   clocks:
     items:
-     - description: GMU clock
-     - description: GPU CX clock
-     - description: GPU AXI clock
-     - description: GPU MEMNOC clock
+      - description: GMU clock
+      - description: GPU CX clock
+      - description: GPU AXI clock
+      - description: GPU MEMNOC clock
 
   clock-names:
     items:
@@ -52,8 +52,8 @@ properties:
 
   interrupts:
     items:
-     - description: GMU HFI interrupt
-     - description: GMU interrupt
+      - description: GMU HFI interrupt
+      - description: GMU interrupt
 
 
   interrupt-names:
@@ -62,14 +62,14 @@ properties:
       - const: gmu
 
   power-domains:
-     items:
-       - description: CX power domain
-       - description: GX power domain
+    items:
+      - description: CX power domain
+      - description: GX power domain
 
   power-domain-names:
-     items:
-       - const: cx
-       - const: gx
+    items:
+      - const: cx
+      - const: gx
 
   iommus:
     maxItems: 1
@@ -90,13 +90,13 @@ required:
   - operating-points-v2
 
 examples:
- - |
-   #include <dt-bindings/clock/qcom,gpucc-sdm845.h>
-   #include <dt-bindings/clock/qcom,gcc-sdm845.h>
-   #include <dt-bindings/interrupt-controller/irq.h>
-   #include <dt-bindings/interrupt-controller/arm-gic.h>
 - |
+    #include <dt-bindings/clock/qcom,gpucc-sdm845.h>
+    #include <dt-bindings/clock/qcom,gcc-sdm845.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-   gmu: gmu@506a000 {
+    gmu: gmu@506a000 {
         compatible="qcom,adreno-gmu-630.2", "qcom,adreno-gmu";
 
         reg = <0x506a000 0x30000>,
@@ -120,4 +120,4 @@ examples:
 
         iommus = <&adreno_smmu 5>;
         operating-points-v2 = <&gmu_opp_table>;
-   };
+    };
index 083d2b9..75a09df 100644 (file)
@@ -24,9 +24,9 @@ properties:
   reg: true
   reset-gpios: true
   vdd-supply:
-     description: core voltage supply
+    description: core voltage supply
   vddio-supply:
-     description: vddio supply
+    description: vddio supply
 
 required:
   - compatible
index 7f5df58..38bc1d1 100644 (file)
@@ -48,12 +48,12 @@ properties:
   port: true
 
 required:
- - compatible
- - reg
- - enable-gpios
- - pp1800-supply
- - avdd-supply
- - avee-supply
 - compatible
 - reg
 - enable-gpios
 - pp1800-supply
 - avdd-supply
 - avee-supply
 
 additionalProperties: false
 
index aa761f6..7adb83e 100644 (file)
@@ -19,9 +19,9 @@ properties:
   backlight: true
   reset-gpios: true
   iovcc-supply:
-     description: regulator that supplies the iovcc voltage
+    description: regulator that supplies the iovcc voltage
   vdd-supply:
-     description: regulator that supplies the vdd voltage
+    description: regulator that supplies the vdd voltage
 
 required:
   - compatible
index 927f1ee..81adb82 100644 (file)
@@ -19,11 +19,11 @@ properties:
   backlight: true
   reset-gpios: true
   avdd-supply:
-     description: regulator that supplies the AVDD voltage
+    description: regulator that supplies the AVDD voltage
   dvdd-supply:
-     description: regulator that supplies the DVDD voltage
+    description: regulator that supplies the DVDD voltage
   cvdd-supply:
-     description: regulator that supplies the CVDD voltage
+    description: regulator that supplies the CVDD voltage
 
 required:
   - compatible
index 177d48c..e89c1ea 100644 (file)
@@ -25,8 +25,7 @@ properties:
   compatible:
     items:
       - enum:
-        - dlink,dir-685-panel
-
+          - dlink,dir-685-panel
       - const: ilitek,ili9322
 
   reset-gpios: true
index a393322..76a9068 100644 (file)
@@ -13,8 +13,7 @@ properties:
   compatible:
     items:
       - enum:
-        - bananapi,lhr050h41
-
+          - bananapi,lhr050h41
       - const: ilitek,ili9881c
 
   backlight: true
index a372bdc..3715882 100644 (file)
@@ -21,9 +21,9 @@ properties:
   backlight: true
   reset-gpios: true
   iovcc-supply:
-     description: regulator that supplies the iovcc voltage
+    description: regulator that supplies the iovcc voltage
   vci-supply:
-     description: regulator that supplies the vci voltage
+    description: regulator that supplies the vci voltage
 
 required:
   - compatible
index b900973..c5944b4 100644 (file)
@@ -19,9 +19,9 @@ properties:
   backlight: true
   reset-gpios: true
   iovcc-supply:
-     description: regulator that supplies the iovcc voltage
+    description: regulator that supplies the iovcc voltage
   vcc-supply:
-     description: regulator that supplies the vcc voltage
+    description: regulator that supplies the vcc voltage
 
 required:
   - compatible
index 73d2ff3..bc92928 100644 (file)
@@ -25,9 +25,9 @@ properties:
   reg: true
   reset-gpios: true
   vdd-supply:
-     description: regulator that supplies the vdd voltage
+    description: regulator that supplies the vdd voltage
   vddi-supply:
-     description: regulator that supplies the vddi voltage
+    description: regulator that supplies the vddi voltage
   backlight: true
 
 required:
index d766c94..4a36aa6 100644 (file)
@@ -27,10 +27,10 @@ properties:
   compatible:
     items:
       - enum:
-        - motorola,droid4-panel        # Panel from Motorola Droid4 phone
-        - nokia,himalaya               # Panel from Nokia N950 phone
-        - tpo,taal                     # Panel from OMAP4 SDP board
-      - const: panel-dsi-cm            # Generic DSI command mode panel compatible fallback
+          - motorola,droid4-panel        # Panel from Motorola Droid4 phone
+          - nokia,himalaya               # Panel from Nokia N950 phone
+          - tpo,taal                     # Panel from OMAP4 SDP board
+      - const: panel-dsi-cm              # Generic DSI command mode panel compatible fallback
 
   reg:
     maxItems: 1
index 182c19c..9bf592d 100644 (file)
@@ -59,7 +59,7 @@ description: |
 properties:
 
   clock-frequency:
-   description: Panel clock in Hz
+    description: Panel clock in Hz
 
   hactive:
     $ref: /schemas/types.yaml#/definitions/uint32
@@ -200,15 +200,15 @@ properties:
     description: Enable double clock mode
 
 required:
- - clock-frequency
- - hactive
- - vactive
- - hfront-porch
- - hback-porch
- - hsync-len
- - vfront-porch
- - vback-porch
- - vsync-len
 - clock-frequency
 - hactive
 - vactive
 - hfront-porch
 - hback-porch
 - hsync-len
 - vfront-porch
 - vback-porch
 - vsync-len
 
 additionalProperties: false
 
index a35ba16..3947779 100644 (file)
@@ -10,8 +10,8 @@ maintainers:
   - Philippe CORNU <philippe.cornu@st.com>
 
 description: |
-             The Raydium Semiconductor Corporation RM68200 is a 5.5" 720x1280 TFT LCD
-             panel connected using a MIPI-DSI video interface.
+  The Raydium Semiconductor Corporation RM68200 is a 5.5" 720x1280 TFT LCD
+  panel connected using a MIPI-DSI video interface.
 
 allOf:
   - $ref: panel-common.yaml#
index 7a685d0..44ce98f 100644 (file)
@@ -18,9 +18,9 @@ properties:
   reg: true
   reset-gpios: true
   vdd3-supply:
-     description: core voltage supply
+    description: core voltage supply
   vci-supply:
-     description: voltage supply for analog circuits
+    description: voltage supply for analog circuits
 
 required:
   - compatible
index b36f39f..076b057 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: Visionox model RM69299 Panels Device Tree Bindings.
 
 maintainers:
- - Harigovindan P <harigovi@codeaurora.org>
 - Harigovindan P <harigovi@codeaurora.org>
 
 description: |
   This binding is for display panels using a Visionox RM692999 panel.
index 3be76d1..69cc7e8 100644 (file)
@@ -45,7 +45,7 @@ properties:
 
   phy-dsi-supply:
     description:
-        Phandle of the regulator that provides the supply voltage.
+      Phandle of the regulator that provides the supply voltage.
 
   ports:
     type: object
@@ -147,4 +147,3 @@ examples:
 
 ...
 
-
index bbd7659..173730d 100644 (file)
@@ -78,7 +78,7 @@ properties:
       - const: vp4
 
   interrupts:
-     items:
+    items:
       - description: common_m DSS Master common
       - description: common_s0 DSS Shared common 0
       - description: common_s1 DSS Shared common 1
index 3bbe952..4cc0112 100644 (file)
@@ -56,8 +56,8 @@ properties:
 
   memory-region:
     description:
-       phandle to a node describing reserved memory (System RAM memory)
-       used by DSP (see bindings/reserved-memory/reserved-memory.txt)
+      phandle to a node describing reserved memory (System RAM memory)
+      used by DSP (see bindings/reserved-memory/reserved-memory.txt)
     maxItems: 1
 
 required:
index c9534d2..822975d 100644 (file)
@@ -177,10 +177,10 @@ properties:
 dependencies:
   # 'vendor,bool-property' is only allowed when 'vendor,string-array-property'
   # is present
-  vendor,bool-property: [ vendor,string-array-property ]
+  vendor,bool-property: [ 'vendor,string-array-property' ]
   # Expressing 2 properties in both orders means all of the set of properties
   # must be present or none of them.
-  vendor,string-array-property: [ vendor,bool-property ]
+  vendor,string-array-property: [ 'vendor,bool-property' ]
 
 required:
   - compatible
index 893d81e..b26d4b4 100644 (file)
@@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: IBM FSI-attached SPI controllers
 
 maintainers:
- - Eddie James <eajames@linux.ibm.com>
 - Eddie James <eajames@linux.ibm.com>
 
 description: |
   This binding describes an FSI CFAM engine called the FSI2SPI. Therefore this
index 4f2cbd8..c213cb9 100644 (file)
@@ -19,10 +19,8 @@ properties:
 
   reg:
     items:
-      - description: the I/O address containing the GPIO controller
-                     registers.
-      - description: the I/O address containing the Chip Common A interrupt
-                     registers.
+      - description: the I/O address containing the GPIO controller registers.
+      - description: the I/O address containing the Chip Common A interrupt registers.
 
   gpio-controller: true
 
index 397d938..3ad2293 100644 (file)
@@ -13,39 +13,39 @@ properties:
   compatible:
     oneOf:
       - items:
-         - enum:
-             - renesas,gpio-r8a7778      # R-Car M1
-             - renesas,gpio-r8a7779      # R-Car H1
-         - const: renesas,rcar-gen1-gpio # R-Car Gen1
+          - enum:
+              - renesas,gpio-r8a7778      # R-Car M1
+              - renesas,gpio-r8a7779      # R-Car H1
+          - const: renesas,rcar-gen1-gpio # R-Car Gen1
 
       - items:
-         - enum:
-             - renesas,gpio-r8a7742      # RZ/G1H
-             - renesas,gpio-r8a7743      # RZ/G1M
-             - renesas,gpio-r8a7744      # RZ/G1N
-             - renesas,gpio-r8a7745      # RZ/G1E
-             - renesas,gpio-r8a77470     # RZ/G1C
-             - renesas,gpio-r8a7790      # R-Car H2
-             - renesas,gpio-r8a7791      # R-Car M2-W
-             - renesas,gpio-r8a7792      # R-Car V2H
-             - renesas,gpio-r8a7793      # R-Car M2-N
-             - renesas,gpio-r8a7794      # R-Car E2
-         - const: renesas,rcar-gen2-gpio # R-Car Gen2 or RZ/G1
+          - enum:
+              - renesas,gpio-r8a7742      # RZ/G1H
+              - renesas,gpio-r8a7743      # RZ/G1M
+              - renesas,gpio-r8a7744      # RZ/G1N
+              - renesas,gpio-r8a7745      # RZ/G1E
+              - renesas,gpio-r8a77470     # RZ/G1C
+              - renesas,gpio-r8a7790      # R-Car H2
+              - renesas,gpio-r8a7791      # R-Car M2-W
+              - renesas,gpio-r8a7792      # R-Car V2H
+              - renesas,gpio-r8a7793      # R-Car M2-N
+              - renesas,gpio-r8a7794      # R-Car E2
+          - const: renesas,rcar-gen2-gpio # R-Car Gen2 or RZ/G1
 
       - items:
-         - enum:
-             - renesas,gpio-r8a774a1     # RZ/G2M
-             - renesas,gpio-r8a774b1     # RZ/G2N
-             - renesas,gpio-r8a774c0     # RZ/G2E
-             - renesas,gpio-r8a7795      # R-Car H3
-             - renesas,gpio-r8a7796      # R-Car M3-W
-             - renesas,gpio-r8a77961     # R-Car M3-W+
-             - renesas,gpio-r8a77965     # R-Car M3-N
-             - renesas,gpio-r8a77970     # R-Car V3M
-             - renesas,gpio-r8a77980     # R-Car V3H
-             - renesas,gpio-r8a77990     # R-Car E3
-             - renesas,gpio-r8a77995     # R-Car D3
-         - const: renesas,rcar-gen3-gpio # R-Car Gen3 or RZ/G2
+          - enum:
+              - renesas,gpio-r8a774a1     # RZ/G2M
+              - renesas,gpio-r8a774b1     # RZ/G2N
+              - renesas,gpio-r8a774c0     # RZ/G2E
+              - renesas,gpio-r8a7795      # R-Car H3
+              - renesas,gpio-r8a7796      # R-Car M3-W
+              - renesas,gpio-r8a77961     # R-Car M3-W+
+              - renesas,gpio-r8a77965     # R-Car M3-N
+              - renesas,gpio-r8a77970     # R-Car V3M
+              - renesas,gpio-r8a77980     # R-Car V3H
+              - renesas,gpio-r8a77990     # R-Car E3
+              - renesas,gpio-r8a77995     # R-Car D3
+          - const: renesas,rcar-gen3-gpio # R-Car Gen3 or RZ/G2
 
   reg:
     maxItems: 1
index e1ac6ff..4843df1 100644 (file)
@@ -26,7 +26,8 @@ properties:
       - description: AXI/master interface clock
       - description: GPU core clock
       - description: Shader clock (only required if GPU has feature PIPE_3D)
-      - description: AHB/slave interface clock (only required if GPU can gate slave interface independently)
+      - description: AHB/slave interface clock (only required if GPU can gate 
+          slave interface independently)
     minItems: 1
     maxItems: 4
 
index af35b77..7898b9d 100644 (file)
@@ -19,7 +19,7 @@ description: |+
 properties:
   compatible:
     enum:
-        - adi,axi-fan-control-1.00.a
+      - adi,axi-fan-control-1.00.a
 
   reg:
     maxItems: 1
index 869f2ae..8105369 100644 (file)
@@ -20,22 +20,22 @@ properties:
           - const: fsl,imx1-i2c
       - items:
           - enum:
-            - fsl,imx25-i2c
-            - fsl,imx27-i2c
-            - fsl,imx31-i2c
-            - fsl,imx50-i2c
-            - fsl,imx51-i2c
-            - fsl,imx53-i2c
-            - fsl,imx6q-i2c
-            - fsl,imx6sl-i2c
-            - fsl,imx6sx-i2c
-            - fsl,imx6sll-i2c
-            - fsl,imx6ul-i2c
-            - fsl,imx7s-i2c
-            - fsl,imx8mq-i2c
-            - fsl,imx8mm-i2c
-            - fsl,imx8mn-i2c
-            - fsl,imx8mp-i2c
+              - fsl,imx25-i2c
+              - fsl,imx27-i2c
+              - fsl,imx31-i2c
+              - fsl,imx50-i2c
+              - fsl,imx51-i2c
+              - fsl,imx53-i2c
+              - fsl,imx6q-i2c
+              - fsl,imx6sl-i2c
+              - fsl,imx6sx-i2c
+              - fsl,imx6sll-i2c
+              - fsl,imx6ul-i2c
+              - fsl,imx7s-i2c
+              - fsl,imx8mq-i2c
+              - fsl,imx8mm-i2c
+              - fsl,imx8mn-i2c
+              - fsl,imx8mp-i2c
           - const: fsl,imx21-i2c
 
   reg:
index da6e8bd..015885d 100644 (file)
@@ -16,8 +16,8 @@ allOf:
         required:
           - mrvl,i2c-polling
     then:
-        required:
-          - interrupts
+      required:
+        - interrupts
 
 properties:
   compatible:
index 5117ad6..cbb8819 100644 (file)
@@ -53,10 +53,10 @@ properties:
 
   standby-gpios:
     description:
-       Must be the device tree identifier of the STBY pin. This pin is used
-       to place the AD7606 into one of two power-down modes, Standby mode or
-       Shutdown mode. As the line is active low, it should be marked
-       GPIO_ACTIVE_LOW.
+      Must be the device tree identifier of the STBY pin. This pin is used
+      to place the AD7606 into one of two power-down modes, Standby mode or
+      Shutdown mode. As the line is active low, it should be marked
+      GPIO_ACTIVE_LOW.
     maxItems: 1
 
   adi,first-data-gpios:
index a0ebb46..cccd303 100644 (file)
@@ -10,7 +10,7 @@ maintainers:
   - Jonathan Cameron <jic23@kernel.org>
 
 description: |
-   Family of simple ADCs with i2c inteface and internal references.
+  Family of simple ADCs with i2c inteface and internal references.
 
 properties:
   compatible:
index e6263b6..0ca9924 100644 (file)
@@ -24,11 +24,11 @@ properties:
           - const: qcom,spmi-adc-rev2
 
       - items:
-        - enum:
-          - qcom,spmi-vadc
-          - qcom,spmi-adc5
-          - qcom,spmi-adc-rev2
-          - qcom,spmi-adc7
+          - enum:
+              - qcom,spmi-vadc
+              - qcom,spmi-adc5
+              - qcom,spmi-adc-rev2
+              - qcom,spmi-adc7
 
   reg:
     description: VADC base address in the SPMI PMIC register map
@@ -97,16 +97,14 @@ patternProperties:
             input signal is multiplied. For example, <1 3> indicates the signal is scaled
             down to 1/3 of its value before ADC measurement.
             If property is not found default value depending on chip will be used.
-        allOf:
-          - $ref: /schemas/types.yaml#/definitions/uint32-array
+        $ref: /schemas/types.yaml#/definitions/uint32-array
         oneOf:
           - items:
-            - const: 1
-            - enum: [ 1, 3, 4, 6, 20, 8, 10 ]
-
+              - const: 1
+              - enum: [ 1, 3, 4, 6, 20, 8, 10 ]
           - items:
-            - const: 10
-            - const: 81
+              - const: 10
+              - const: 81
 
       qcom,ratiometric:
         description: |
index bcff82a..1bb7619 100644 (file)
@@ -17,10 +17,10 @@ properties:
       - const: rockchip,rk3399-saradc
       - items:
           - enum:
-            - rockchip,px30-saradc
-            - rockchip,rk3308-saradc
-            - rockchip,rk3328-saradc
-            - rockchip,rv1108-saradc
+              - rockchip,px30-saradc
+              - rockchip,rk3308-saradc
+              - rockchip,rk3328-saradc
+              - rockchip,rv1108-saradc
           - const: rockchip,rk3399-saradc
 
   reg:
index 1c6d496..5342360 100644 (file)
@@ -7,8 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
 title: HMC425A 6-bit Digital Step Attenuator
 
 maintainers:
-- Michael Hennerich <michael.hennerich@analog.com>
-- Beniamin Bia <beniamin.bia@analog.com>
+  - Michael Hennerich <michael.hennerich@analog.com>
+  - Beniamin Bia <beniamin.bia@analog.com>
 
 description: |
   Digital Step Attenuator IIO device with gpio interface.
index 69e8931..9a89b34 100644 (file)
@@ -31,10 +31,10 @@ properties:
       - atlas,co2-ezo
 
   reg:
-     maxItems: 1
+    maxItems: 1
 
   interrupts:
-     maxItems: 1
+    maxItems: 1
 
 required:
   - compatible
index 58d81ca..82424e0 100644 (file)
@@ -61,17 +61,17 @@ properties:
         const: 0
 
       adi,range-microamp:
-          description: Output range of the channel.
-          oneOf:
-            - items:
-                - const: 0
-                - const: 300000
-            - items:
-                - const: -60000
-                - const: 0
-            - items:
-                - const: -60000
-                - const: 300000
+        description: Output range of the channel.
+        oneOf:
+          - items:
+              - const: 0
+              - const: 300000
+          - items:
+              - const: -60000
+              - const: 0
+          - items:
+              - const: -60000
+              - const: 300000
 
   channel@1:
     description: Represents an external channel which are
@@ -84,10 +84,10 @@ properties:
         const: 1
 
       adi,range-microamp:
-          description: Output range of the channel.
-          items:
-            - const: 0
-            - enum: [ 140000, 250000 ]
+        description: Output range of the channel.
+        items:
+          - const: 0
+          - enum: [140000, 250000]
 
   channel@2:
     description: Represents an external channel which are
@@ -100,10 +100,10 @@ properties:
         const: 2
 
       adi,range-microamp:
-          description: Output range of the channel.
-          items:
-            - const: 0
-            - enum: [ 55000, 150000 ]
+        description: Output range of the channel.
+        items:
+          - const: 0
+          - enum: [55000, 150000]
 
 patternProperties:
   "^channel@([3-5])$":
@@ -116,19 +116,19 @@ patternProperties:
         maximum: 5
 
       adi,range-microamp:
-          description: Output range of the channel.
-          items:
-            - const: 0
-            - enum: [ 45000, 100000 ]
+        description: Output range of the channel.
+        items:
+          - const: 0
+          - enum: [45000, 100000]
 
 required:
-- reg
-- channel@0
-- channel@1
-- channel@2
-- channel@3
-- channel@4
-- channel@5
+  - reg
+  - channel@0
+  - channel@1
+  - channel@2
+  - channel@3
+  - channel@4
+  - channel@5
 
 examples:
   - |
index da8f2e8..58887a4 100644 (file)
@@ -36,15 +36,15 @@ required:
 additionalProperties: false
 
 examples:
-- |
-  i2c {
-      #address-cells = <1>;
-      #size-cells = <0>;
-
-      light-sensor@51 {
-              compatible = "vishay,vcnl4200";
-              reg = <0x51>;
-              proximity-near-level = <220>;
-      };
-  };
+  - |
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        light-sensor@51 {
+            compatible = "vishay,vcnl4200";
+            reg = <0x51>;
+            proximity-near-level = <220>;
+        };
+    };
 ...
index f4393bf..f0b336a 100644 (file)
@@ -13,15 +13,15 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - asahi-kasei,ak8975
-        - asahi-kasei,ak8963
-        - asahi-kasei,ak09911
-        - asahi-kasei,ak09912
+          - asahi-kasei,ak8975
+          - asahi-kasei,ak8963
+          - asahi-kasei,ak09911
+          - asahi-kasei,ak09912
       - enum:
-        - ak8975
-        - ak8963
-        - ak09911
-        - ak09912
+          - ak8975
+          - ak8963
+          - ak09911
+          - ak09912
         deprecated: true
 
   reg:
index 4190253..51dba64 100644 (file)
@@ -39,8 +39,8 @@ properties:
     description:
       The driver current for the LED used in proximity sensing.
     enum: [0, 10000, 20000, 30000, 40000, 50000, 60000, 70000, 80000, 90000,
-          100000, 110000, 120000, 130000, 140000, 150000, 160000, 170000,
-          180000, 190000, 200000]
+           100000, 110000, 120000, 130000, 140000, 150000, 160000, 170000,
+           180000, 190000, 200000]
     default: 20000
 
 required:
index 40ccbe7..0f79d9a 100644 (file)
@@ -307,7 +307,7 @@ patternProperties:
           mode.
         $ref: /schemas/types.yaml#/definitions/uint32
         enum: [0, 250, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000,
-          500000, 1000000]
+               500000, 1000000]
 
       adi,custom-thermistor:
         description:
index 7432c6e..f21db81 100644 (file)
@@ -24,19 +24,19 @@ properties:
       - const: fsl,imx21-kpp
       - items:
           - enum:
-            - fsl,imx25-kpp
-            - fsl,imx27-kpp
-            - fsl,imx31-kpp
-            - fsl,imx35-kpp
-            - fsl,imx51-kpp
-            - fsl,imx53-kpp
-            - fsl,imx50-kpp
-            - fsl,imx6q-kpp
-            - fsl,imx6sx-kpp
-            - fsl,imx6sl-kpp
-            - fsl,imx6sll-kpp
-            - fsl,imx6ul-kpp
-            - fsl,imx7d-kpp
+              - fsl,imx25-kpp
+              - fsl,imx27-kpp
+              - fsl,imx31-kpp
+              - fsl,imx35-kpp
+              - fsl,imx51-kpp
+              - fsl,imx53-kpp
+              - fsl,imx50-kpp
+              - fsl,imx6q-kpp
+              - fsl,imx6sx-kpp
+              - fsl,imx6sl-kpp
+              - fsl,imx6sll-kpp
+              - fsl,imx6ul-kpp
+              - fsl,imx7d-kpp
           - const: fsl,imx21-kpp
 
   reg:
index 8c73e52..3225c8d 100644 (file)
@@ -51,7 +51,7 @@ required:
   - touchscreen-max-pressure
 
 examples:
-- |
+  - |
     #include <dt-bindings/interrupt-controller/irq.h>
     i2c {
       #address-cells = <1>;
index 024b262..4ce1094 100644 (file)
@@ -20,11 +20,11 @@ maintainers:
 allOf:
   - $ref: touchscreen.yaml#
   - if:
-     properties:
-       compatible:
-         contains:
-           enum:
-             - evervision,ev-ft5726
+      properties:
+        compatible:
+          contains:
+            enum:
+              - evervision,ev-ft5726
 
     then:
       properties:
index e81cfa5..da5b0d8 100644 (file)
@@ -35,9 +35,8 @@ properties:
     maxItems: 1
 
   irq-gpios:
-    description: GPIO pin used for IRQ.
-                 The driver uses the interrupt gpio pin as
-                 output to reset the device.
+    description: GPIO pin used for IRQ. The driver uses the interrupt gpio pin
+      as output to reset the device.
     maxItems: 1
 
   reset-gpios:
index d7dac16..36dc7b5 100644 (file)
@@ -33,8 +33,8 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint32
 
   touchscreen-min-pressure:
-    description: minimum pressure on the touchscreen to be achieved in order for the
-                 touchscreen driver to report a touch event.
+    description: minimum pressure on the touchscreen to be achieved in order
+      for the touchscreen driver to report a touch event.
     $ref: /schemas/types.yaml#/definitions/uint32
 
   touchscreen-fuzz-x:
@@ -46,13 +46,13 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint32
 
   touchscreen-fuzz-pressure:
-    description: pressure noise value of the absolute input device (arbitrary range
-                 dependent on the controller)
+    description: pressure noise value of the absolute input device (arbitrary
+      range dependent on the controller)
     $ref: /schemas/types.yaml#/definitions/uint32
 
   touchscreen-average-samples:
-    description: Number of data samples which are averaged for each read (valid values
-                 dependent on the controller)
+    description: Number of data samples which are averaged for each read (valid
+      values dependent on the controller)
     $ref: /schemas/types.yaml#/definitions/uint32
 
   touchscreen-inverted-x:
index ff09550..a887373 100644 (file)
@@ -25,17 +25,17 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - fsl,imx8mn-nic
-          - fsl,imx8mm-nic
-          - fsl,imx8mq-nic
-        - const: fsl,imx8m-nic
+          - enum:
+              - fsl,imx8mn-nic
+              - fsl,imx8mm-nic
+              - fsl,imx8mq-nic
+          - const: fsl,imx8m-nic
       - items:
-        - enum:
-          - fsl,imx8mn-noc
-          - fsl,imx8mm-noc
-          - fsl,imx8mq-noc
-        - const: fsl,imx8m-noc
+          - enum:
+              - fsl,imx8mn-noc
+              - fsl,imx8mm-noc
+              - fsl,imx8mq-noc
+          - const: fsl,imx8m-noc
       - const: fsl,imx8m-nic
 
   reg:
index d01bac8..8659048 100644 (file)
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/interconnect/qcom,sc7180.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title:  Qualcomm SC7180 Network-On-Chip Interconnect
+title: Qualcomm SC7180 Network-On-Chip Interconnect
 
 maintainers:
   - Odelu Kukatla <okukatla@codeaurora.org>
index 7453674..dab17c0 100644 (file)
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/interconnect/qcom,sdm845.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title:  Qualcomm SDM845 Network-On-Chip Interconnect
+title: Qualcomm SDM845 Network-On-Chip Interconnect
 
 maintainers:
   - Georgi Djakov <georgi.djakov@linaro.org>
index 96f8803..0688996 100644 (file)
@@ -42,8 +42,8 @@ properties:
       - items:
           - const: arm,gic-400
           - enum:
-             - arm,cortex-a15-gic
-             - arm,cortex-a7-gic
+              - arm,cortex-a15-gic
+              - arm,cortex-a7-gic
 
       - items:
           - const: arm,arm1176jzf-devchip-gic
index 28b27e1..02a3cf4 100644 (file)
@@ -16,20 +16,20 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4740-intc
-        - ingenic,jz4760-intc
-        - ingenic,jz4780-intc
+          - ingenic,jz4740-intc
+          - ingenic,jz4760-intc
+          - ingenic,jz4780-intc
       - items:
-        - enum:
-          - ingenic,jz4775-intc
-          - ingenic,jz4770-intc
-        - const: ingenic,jz4760-intc
+          - enum:
+              - ingenic,jz4775-intc
+              - ingenic,jz4770-intc
+          - const: ingenic,jz4760-intc
       - items:
-        - const: ingenic,x1000-intc
-        - const: ingenic,jz4780-intc
+          - const: ingenic,x1000-intc
+          - const: ingenic,jz4780-intc
       - items:
-        - const: ingenic,jz4725b-intc
-        - const: ingenic,jz4740-intc
+          - const: ingenic,jz4725b-intc
+          - const: ingenic,jz4740-intc
 
   "#interrupt-cells":
     const: 1
index 9f0eb3a..ce6aaff 100644 (file)
@@ -42,14 +42,13 @@ properties:
       Specifies the list of CPU interrupt vectors to which the GIC may not
       route interrupts. This property is ignored if the CPU is started in EIC
       mode.
-    allOf:
-      - $ref: /schemas/types.yaml#definitions/uint32-array
-      - minItems: 1
-        maxItems: 6
-        uniqueItems: true
-        items:
-          minimum: 2
-          maximum: 7
+    $ref: /schemas/types.yaml#definitions/uint32-array
+    minItems: 1
+    maxItems: 6
+    uniqueItems: true
+    items:
+      minimum: 2
+      maximum: 7
 
   mti,reserved-ipi-vectors:
     description: |
@@ -57,13 +56,12 @@ properties:
       It accepts two values: the 1st is the starting interrupt and the 2nd is
       the size of the reserved range. If not specified, the driver will
       allocate the last (2 * number of VPEs in the system).
-    allOf:
-      - $ref: /schemas/types.yaml#definitions/uint32-array
-      - items:
-          - minimum: 0
-            maximum: 254
-          - minimum: 2
-            maximum: 254
+    $ref: /schemas/types.yaml#definitions/uint32-array
+    items:
+      - minimum: 0
+        maximum: 254
+      - minimum: 2
+        maximum: 254
 
   timer:
     type: object
index 32e0896..47938e3 100644 (file)
@@ -79,7 +79,8 @@ properties:
     description: |
       kHz; switching frequency.
     $ref: /schemas/types.yaml#/definitions/uint32
-    enum: [ 600, 640, 685, 738, 800, 872, 960, 1066, 1200, 1371, 1600, 1920, 2400, 3200, 4800, 9600 ]
+    enum: [ 600, 640, 685, 738, 800, 872, 960, 1066, 1200, 1371, 1600, 1920, 
+            2400, 3200, 4800, 9600 ]
 
   qcom,ovp:
     description: |
index 3b35eb5..8a3470b 100644 (file)
@@ -29,12 +29,12 @@ properties:
       - const: fsl,imx8-mu-scu
       - items:
           - enum:
-            - fsl,imx7s-mu
-            - fsl,imx8mq-mu
-            - fsl,imx8mm-mu
-            - fsl,imx8mn-mu
-            - fsl,imx8mp-mu
-            - fsl,imx8qxp-mu
+              - fsl,imx7s-mu
+              - fsl,imx8mq-mu
+              - fsl,imx8mm-mu
+              - fsl,imx8mn-mu
+              - fsl,imx8mp-mu
+              - fsl,imx8qxp-mu
           - const: fsl,imx6sx-mu
       - description: To communicate with i.MX8 SCU with fast IPC
         items:
index 4ac2123..168beeb 100644 (file)
@@ -24,7 +24,7 @@ properties:
   compatible:
     items:
       - enum:
-        - qcom,sm8250-ipcc
+          - qcom,sm8250-ipcc
       - const: qcom,ipcc
 
   reg:
index 75196d1..a258832 100644 (file)
@@ -20,8 +20,8 @@ properties:
     oneOf:
       - const: allwinner,sun8i-a83t-de2-rotate
       - items:
-        - const: allwinner,sun50i-a64-de2-rotate
-        - const: allwinner,sun8i-a83t-de2-rotate
+          - const: allwinner,sun50i-a64-de2-rotate
+          - const: allwinner,sun8i-a83t-de2-rotate
 
   reg:
     maxItems: 1
index 8707df6..6a56214 100644 (file)
@@ -20,8 +20,8 @@ properties:
     oneOf:
       - const: allwinner,sun8i-h3-deinterlace
       - items:
-        - const: allwinner,sun50i-a64-deinterlace
-        - const: allwinner,sun8i-h3-deinterlace
+          - const: allwinner,sun50i-a64-deinterlace
+          - const: allwinner,sun8i-h3-deinterlace
 
   reg:
     maxItems: 1
index e0084b2..d8c54f9 100644 (file)
@@ -17,17 +17,17 @@ properties:
   compatible:
     items:
       - enum:
-        - adi,adv7180
-        - adi,adv7180cp
-        - adi,adv7180st
-        - adi,adv7182
-        - adi,adv7280
-        - adi,adv7280-m
-        - adi,adv7281
-        - adi,adv7281-m
-        - adi,adv7281-ma
-        - adi,adv7282
-        - adi,adv7282-m
+          - adi,adv7180
+          - adi,adv7180cp
+          - adi,adv7180st
+          - adi,adv7182
+          - adi,adv7280
+          - adi,adv7280-m
+          - adi,adv7281
+          - adi,adv7281-m
+          - adi,adv7281-ma
+          - adi,adv7282
+          - adi,adv7282-m
 
   reg:
     maxItems: 1
@@ -58,17 +58,16 @@ allOf:
   - if:
       properties:
         compatible:
-          items:
-            - enum:
-              - adi,adv7180
-              - adi,adv7182
-              - adi,adv7280
-              - adi,adv7280-m
-              - adi,adv7281
-              - adi,adv7281-m
-              - adi,adv7281-ma
-              - adi,adv7282
-              - adi,adv7282-m
+          enum:
+            - adi,adv7180
+            - adi,adv7182
+            - adi,adv7280
+            - adi,adv7280-m
+            - adi,adv7281
+            - adi,adv7281-m
+            - adi,adv7281-ma
+            - adi,adv7282
+            - adi,adv7282-m
     then:
       required:
         - port
index cb96e95..21864ab 100644 (file)
@@ -38,39 +38,36 @@ properties:
   dongwoon,aac-mode:
     description:
       Indication of AAC mode select.
-    allOf:
-      - $ref: "/schemas/types.yaml#/definitions/uint32"
-      - enum:
-          - 1    #  AAC2 mode(operation time# 0.48 x Tvib)
-          - 2    #  AAC3 mode(operation time# 0.70 x Tvib)
-          - 3    #  AAC4 mode(operation time# 0.75 x Tvib)
-          - 5    #  AAC8 mode(operation time# 1.13 x Tvib)
-        default: 2
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    enum:
+      - 1    #  AAC2 mode(operation time# 0.48 x Tvib)
+      - 2    #  AAC3 mode(operation time# 0.70 x Tvib)
+      - 3    #  AAC4 mode(operation time# 0.75 x Tvib)
+      - 5    #  AAC8 mode(operation time# 1.13 x Tvib)
+    default: 2
 
   dongwoon,aac-timing:
     description:
       Number of AAC Timing count that controlled by one 6-bit period of
       vibration register AACT[5:0], the unit of which is 100 us.
-    allOf:
-      - $ref: "/schemas/types.yaml#/definitions/uint32"
-      - default: 0x20
-        minimum: 0x00
-        maximum: 0x3f
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    default: 0x20
+    minimum: 0x00
+    maximum: 0x3f
 
   dongwoon,clock-presc:
     description:
       Indication of VCM internal clock dividing rate select, as one multiple
       factor to calculate VCM ring periodic time Tvib.
-    allOf:
-      - $ref: "/schemas/types.yaml#/definitions/uint32"
-      - enum:
-          - 0    #  Dividing Rate -  2
-          - 1    #  Dividing Rate -  1
-          - 2    #  Dividing Rate -  1/2
-          - 3    #  Dividing Rate -  1/4
-          - 4    #  Dividing Rate -  8
-          - 5    #  Dividing Rate -  4
-        default: 1
+    $ref: "/schemas/types.yaml#/definitions/uint32"
+    enum:
+      - 0    #  Dividing Rate -  2
+      - 1    #  Dividing Rate -  1
+      - 2    #  Dividing Rate -  1/2
+      - 3    #  Dividing Rate -  1/4
+      - 4    #  Dividing Rate -  8
+      - 5    #  Dividing Rate -  4
+    default: 1
 
 required:
   - compatible
index 5ad4b8c..107c862 100644 (file)
@@ -5,7 +5,7 @@
 $id: http://devicetree.org/schemas/media/i2c/imi,rdacm2x-gmsl.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title:  IMI D&D RDACM20 and RDACM21 Automotive Camera Platforms
+title: IMI D&D RDACM20 and RDACM21 Automotive Camera Platforms
 
 maintainers:
   - Jacopo Mondi <jacopo+renesas@jmondi.org>
index e7b5431..9ea8270 100644 (file)
@@ -49,7 +49,7 @@ properties:
   gpio-controller: true
 
   '#gpio-cells':
-      const: 2
+    const: 2
 
   ports:
     type: object
index 1956b2a..cde8555 100644 (file)
@@ -138,4 +138,5 @@ examples:
             };
         };
     };
-...
\ No newline at end of file
+...
+
index c9e0682..6d28258 100644 (file)
@@ -19,15 +19,15 @@ properties:
   compatible:
     items:
       - enum:
-        - renesas,r8a774a1-csi2 # RZ/G2M
-        - renesas,r8a774b1-csi2 # RZ/G2N
-        - renesas,r8a774c0-csi2 # RZ/G2E
-        - renesas,r8a7795-csi2  # R-Car H3
-        - renesas,r8a7796-csi2  # R-Car M3-W
-        - renesas,r8a77965-csi2 # R-Car M3-N
-        - renesas,r8a77970-csi2 # R-Car V3M
-        - renesas,r8a77980-csi2 # R-Car V3H
-        - renesas,r8a77990-csi2 # R-Car E3
+          - renesas,r8a774a1-csi2 # RZ/G2M
+          - renesas,r8a774b1-csi2 # RZ/G2N
+          - renesas,r8a774c0-csi2 # RZ/G2E
+          - renesas,r8a7795-csi2  # R-Car H3
+          - renesas,r8a7796-csi2  # R-Car M3-W
+          - renesas,r8a77965-csi2 # R-Car M3-N
+          - renesas,r8a77970-csi2 # R-Car V3M
+          - renesas,r8a77980-csi2 # R-Car V3H
+          - renesas,r8a77990-csi2 # R-Car E3
 
   reg:
     maxItems: 1
index 2b62945..c81dbc3 100644 (file)
@@ -31,8 +31,8 @@ properties:
     oneOf:
       - const: vdpu
       - items:
-        - const: vepu
-        - const: vdpu
+          - const: vepu
+          - const: vdpu
 
   clocks:
     maxItems: 2
index 7b9407c..2961a5b 100644 (file)
@@ -25,7 +25,7 @@ properties:
   compatible:
     items:
       - enum:
-        - xlnx,mipi-csi2-rx-subsystem-5.0
+          - xlnx,mipi-csi2-rx-subsystem-5.0
 
   reg:
     maxItems: 1
@@ -65,13 +65,12 @@ properties:
       0x2d - RAW14
       0x2e - RAW16
       0x2f - RAW20
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/uint32
-      - anyOf:
-        - minimum: 0x1e
-        - maximum: 0x24
-        - minimum: 0x28
-        - maximum: 0x2f
+    $ref: /schemas/types.yaml#/definitions/uint32
+    oneOf:
+      - minimum: 0x1e
+        maximum: 0x24
+      - minimum: 0x28
+        maximum: 0x2f
 
   xlnx,vfb:
     type: boolean
index dee5131..6848413 100644 (file)
@@ -15,12 +15,12 @@ properties:
       - const: fsl,imx6q-mmdc
       - items:
           - enum:
-            - fsl,imx6qp-mmdc
-            - fsl,imx6sl-mmdc
-            - fsl,imx6sll-mmdc
-            - fsl,imx6sx-mmdc
-            - fsl,imx6ul-mmdc
-            - fsl,imx7ulp-mmdc
+              - fsl,imx6qp-mmdc
+              - fsl,imx6sl-mmdc
+              - fsl,imx6sll-mmdc
+              - fsl,imx6sx-mmdc
+              - fsl,imx6ul-mmdc
+              - fsl,imx7ulp-mmdc
           - const: fsl,imx6q-mmdc
 
   reg:
index 17ba45a..fe0ce19 100644 (file)
@@ -16,11 +16,11 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4740-nemc
-        - ingenic,jz4780-nemc
+          - ingenic,jz4740-nemc
+          - ingenic,jz4780-nemc
       - items:
-        - const: ingenic,jz4725b-nemc
-        - const: ingenic,jz4740-nemc
+          - const: ingenic,jz4725b-nemc
+          - const: ingenic,jz4740-nemc
 
   "#address-cells":
     const: 2
index 6600056..7bfe120 100644 (file)
@@ -26,10 +26,10 @@ properties:
   compatible:
     items:
       - enum:
-        - renesas,r8a77970-rpc-if       # R-Car V3M
-        - renesas,r8a77980-rpc-if       # R-Car V3H
-        - renesas,r8a77995-rpc-if       # R-Car D3
-      - const: renesas,rcar-gen3-rpc-if # a generic R-Car gen3 device
+          - renesas,r8a77970-rpc-if       # R-Car V3M
+          - renesas,r8a77980-rpc-if       # R-Car V3H
+          - renesas,r8a77995-rpc-if       # R-Car D3
+      - const: renesas,rcar-gen3-rpc-if   # a generic R-Car gen3 device
 
   reg:
     items:
index a5531f6..499c62c 100644 (file)
@@ -98,11 +98,11 @@ allOf:
           description:
             Databus power supply.
   - if:
-     properties:
-       compatible:
-         contains:
-           enum:
-             - cirrus,cs47l15
+      properties:
+        compatible:
+          contains:
+            enum:
+              - cirrus,cs47l15
     then:
       required:
         - MICVDD-supply
@@ -174,24 +174,24 @@ properties:
         "mclk3" For the clock supplied on MCLK3.
     oneOf:
       - items:
-        - const: mclk1
+          - const: mclk1
       - items:
-        - const: mclk2
+          - const: mclk2
       - items:
-        - const: mclk3
+          - const: mclk3
       - items:
-        - const: mclk1
-        - const: mclk2
+          - const: mclk1
+          - const: mclk2
       - items:
-        - const: mclk1
-        - const: mclk3
+          - const: mclk1
+          - const: mclk3
       - items:
-        - const: mclk2
-        - const: mclk3
+          - const: mclk2
+          - const: mclk3
       - items:
-        - const: mclk1
-        - const: mclk2
-        - const: mclk3
+          - const: mclk1
+          - const: mclk2
+          - const: mclk3
 
   AVDD-supply:
     description:
diff --git a/Documentation/devicetree/bindings/mfd/cros-ec.txt b/Documentation/devicetree/bindings/mfd/cros-ec.txt
deleted file mode 100644 (file)
index 4860eab..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-ChromeOS Embedded Controller
-
-Google's ChromeOS EC is a Cortex-M device which talks to the AP and
-implements various function such as keyboard and battery charging.
-
-The EC can be connect through various means (I2C, SPI, LPC, RPMSG) and the
-compatible string used depends on the interface. Each connection method has
-its own driver which connects to the top level interface-agnostic EC driver.
-Other Linux driver (such as cros-ec-keyb for the matrix keyboard) connect to
-the top-level driver.
-
-Required properties (I2C):
-- compatible: "google,cros-ec-i2c"
-- reg: I2C slave address
-
-Required properties (SPI):
-- compatible: "google,cros-ec-spi"
-- reg: SPI chip select
-
-Required properties (RPMSG):
-- compatible: "google,cros-ec-rpmsg"
-
-Optional properties (SPI):
-- google,cros-ec-spi-pre-delay: Some implementations of the EC need a little
-  time to wake up from sleep before they can receive SPI transfers at a high
-  clock rate. This property specifies the delay, in usecs, between the
-  assertion of the CS to the start of the first clock pulse.
-- google,cros-ec-spi-msg-delay: Some implementations of the EC require some
-  additional processing time in order to accept new transactions. If the delay
-  between transactions is not long enough the EC may not be able to respond
-  properly to subsequent transactions and cause them to hang. This property
-  specifies the delay, in usecs, introduced between transactions to account
-  for the time required by the EC to get back into a state in which new data
-  can be accepted.
-
-Required properties (LPC):
-- compatible: "google,cros-ec-lpc"
-- reg: List of (IO address, size) pairs defining the interface uses
-
-Optional properties (all):
-- google,has-vbc-nvram: Some implementations of the EC include a small
-  nvram space used to store verified boot context data. This boolean flag
-  is used to specify whether this nvram is present or not.
-
-Example for I2C:
-
-i2c@12ca0000 {
-       cros-ec@1e {
-               reg = <0x1e>;
-               compatible = "google,cros-ec-i2c";
-               interrupts = <14 0>;
-               interrupt-parent = <&wakeup_eint>;
-               wakeup-source;
-       };
-
-
-Example for SPI:
-
-spi@131b0000 {
-       ec@0 {
-               compatible = "google,cros-ec-spi";
-               reg = <0x0>;
-               interrupts = <14 0>;
-               interrupt-parent = <&wakeup_eint>;
-               wakeup-source;
-               spi-max-frequency = <5000000>;
-               controller-data {
-               cs-gpio = <&gpf0 3 4 3 0>;
-               samsung,spi-cs;
-               samsung,spi-feedback-delay = <2>;
-               };
-       };
-};
-
-
-Example for LPC is not supplied as it is not yet implemented.
index 487a844..9b6eb50 100644 (file)
@@ -79,18 +79,19 @@ properties:
             description: |
               conversion mode:
                 0 - temperature, in C*10
-                1 - pre-scaled voltage value
+                1 - pre-scaled 24-bit voltage value
                 2 - scaled voltage based on an optional resistor divider
                     and optional offset
+                3 - pre-scaled 16-bit voltage value
             $ref: /schemas/types.yaml#/definitions/uint32
-            enum: [0, 1, 2]
+            enum: [0, 1, 2, 3]
 
           gw,voltage-divider-ohms:
             description: Values of resistors for divider on raw ADC input
             maxItems: 2
             items:
-             minimum: 1000
-             maximum: 1000000
+              minimum: 1000
+              maximum: 1000000
 
           gw,voltage-offset-microvolt:
             description: |
diff --git a/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml b/Documentation/devicetree/bindings/mfd/google,cros-ec.yaml
new file mode 100644 (file)
index 0000000..6a7279a
--- /dev/null
@@ -0,0 +1,129 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/google,cros-ec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ChromeOS Embedded Controller
+
+maintainers:
+  - Benson Leung <bleung@chromium.org>
+  - Enric Balletbo i Serra <enric.balletbo@collabora.com>
+  - Guenter Roeck <groeck@chromium.org>
+
+description:
+  Google's ChromeOS EC is a microcontroller which talks to the AP and
+  implements various functions such as keyboard and battery charging.
+  The EC can be connected through various interfaces (I2C, SPI, and others)
+  and the compatible string specifies which interface is being used.
+
+properties:
+  compatible:
+    oneOf:
+      - description:
+          For implementations of the EC is connected through I2C.
+        const: google,cros-ec-i2c
+      - description:
+          For implementations of the EC is connected through SPI.
+        const: google,cros-ec-spi
+      - description:
+          For implementations of the EC is connected through RPMSG.
+        const: google,cros-ec-rpmsg
+
+  google,cros-ec-spi-pre-delay:
+    description:
+      This property specifies the delay in usecs between the
+      assertion of the CS and the first clock pulse.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - default: 0
+      - minimum: 0
+
+  google,cros-ec-spi-msg-delay:
+    description:
+      This property specifies the delay in usecs between messages.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32
+      - default: 0
+      - minimum: 0
+
+  google,has-vbc-nvram:
+    description:
+      Some implementations of the EC include a small nvram space used to
+      store verified boot context data. This boolean flag is used to specify
+      whether this nvram is present or not.
+    type: boolean
+
+  spi-max-frequency:
+    description: Maximum SPI frequency of the device in Hz.
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+required:
+  - compatible
+
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - google,cros-ec-i2c
+          - google,cros-ec-rpmsg
+then:
+  properties:
+    google,cros-ec-spi-pre-delay: false
+    google,cros-ec-spi-msg-delay: false
+    spi-max-frequency: false
+
+additionalProperties: false
+
+examples:
+  # Example for I2C
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    i2c0 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        cros-ec@1e {
+            compatible = "google,cros-ec-i2c";
+            reg = <0x1e>;
+            interrupts = <6 0>;
+            interrupt-parent = <&gpio0>;
+        };
+    };
+
+  # Example for SPI
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi0 {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        cros-ec@0 {
+            compatible = "google,cros-ec-spi";
+            reg = <0x0>;
+            google,cros-ec-spi-msg-delay = <30>;
+            google,cros-ec-spi-pre-delay = <10>;
+            interrupts = <99 0>;
+            interrupt-parent = <&gpio7>;
+            spi-max-frequency = <5000000>;
+        };
+    };
+
+  # Example for RPMSG
+  - |
+    scp0 {
+        cros-ec {
+            compatible = "google,cros-ec-rpmsg";
+        };
+    };
+...
diff --git a/Documentation/devicetree/bindings/mfd/khadas,mcu.yaml b/Documentation/devicetree/bindings/mfd/khadas,mcu.yaml
new file mode 100644 (file)
index 0000000..a3b976f
--- /dev/null
@@ -0,0 +1,44 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/khadas,mcu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Khadas on-board Microcontroller Device Tree Bindings
+
+maintainers:
+  - Neil Armstrong <narmstrong@baylibre.com>
+
+description: |
+  Khadas embeds a microcontroller on their VIM and Edge boards adding some
+  system feature as PWM Fan control (for VIM2 rev14 or VIM3), User memory
+  storage, IR/Key resume control, system power LED control and more.
+
+properties:
+  compatible:
+    enum:
+      - khadas,mcu # MCU revision is discoverable
+
+  "#cooling-cells": # Only needed for boards having FAN control feature
+    const: 2
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+
+additionalProperties: false
+
+examples:
+  - |
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      khadas_mcu: system-controller@18 {
+        compatible = "khadas,mcu";
+        reg = <0x18>;
+        #cooling-cells = <2>;
+      };
+    };
index e675611..8bcea8d 100644 (file)
@@ -33,6 +33,9 @@ properties:
     items:
       - const: mux
 
+  interrupts:
+    maxItems: 1
+
   "#address-cells":
     const: 1
 
@@ -106,11 +109,13 @@ additionalProperties: false
 examples:
   - |
     #include <dt-bindings/clock/stm32mp1-clks.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
     timer@40002400 {
       compatible = "st,stm32-lptimer";
       reg = <0x40002400 0x400>;
       clocks = <&timer_clk>;
       clock-names = "mux";
+      interrupts-extended = <&exti 47 IRQ_TYPE_LEVEL_HIGH>;
       #address-cells = <1>;
       #size-cells = <0>;
 
diff --git a/Documentation/devicetree/bindings/mfd/st,stmfx.yaml b/Documentation/devicetree/bindings/mfd/st,stmfx.yaml
new file mode 100644 (file)
index 0000000..888ab4b
--- /dev/null
@@ -0,0 +1,122 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/st,stmfx.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: STMicroelectonics Multi-Function eXpander (STMFX) bindings
+
+description: ST Multi-Function eXpander (STMFX) is a slave controller using I2C for
+               communication with the main MCU. Its main features are GPIO expansion,
+               main MCU IDD measurement (IDD is the amount of current that flows
+               through VDD) and resistive touchscreen controller.
+
+maintainers:
+  - Amelie Delaunay <amelie.delaunay@st.com>
+
+properties:
+  compatible:
+    const: st,stmfx-0300
+
+  reg:
+    enum: [ 0x42, 0x43 ]
+
+  interrupts:
+    maxItems: 1
+
+  drive-open-drain: true
+
+  vdd-supply:
+    maxItems: 1
+
+  pinctrl:
+    type: object
+
+    properties:
+      compatible:
+        const: st,stmfx-0300-pinctrl
+
+      "#gpio-cells":
+        const: 2
+
+      "#interrupt-cells":
+        const: 2
+
+      gpio-controller: true
+
+      interrupt-controller: true
+
+      gpio-ranges:
+        description: if all STMFX pins[24:0] are available (no other STMFX function in use),
+                     you should use gpio-ranges = <&stmfx_pinctrl 0 0 24>;
+                     if agpio[3:0] are not available (STMFX Touchscreen function in use),
+                     you should use gpio-ranges = <&stmfx_pinctrl 0 0 16>, <&stmfx_pinctrl 20 20 4>;
+                     if agpio[7:4] are not available (STMFX IDD function in use),
+                     you should use gpio-ranges = <&stmfx_pinctrl 0 0 20>;
+        maxItems: 1
+
+    patternProperties:
+      "^[a-zA-Z]*-pins$":
+        type: object
+
+        allOf:
+          - $ref: ../pinctrl/pinmux-node.yaml
+
+        properties:
+          pins: true
+          bias-disable: true
+          bias-pull-up: true
+          bias-pull-pin-default: true
+          bias-pull-down: true
+          drive-open-drain: true
+          drive-push-pull: true
+          output-high: true
+          output-low: true
+
+    additionalProperties: false
+
+    required:
+      - compatible
+      - "#gpio-cells"
+      - "#interrupt-cells"
+      - gpio-controller
+      - interrupt-controller
+      - gpio-ranges
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    i2c {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      stmfx@42 {
+        compatible = "st,stmfx-0300";
+        reg = <0x42>;
+        interrupts = <8 IRQ_TYPE_EDGE_RISING>;
+        interrupt-parent = <&gpioi>;
+        vdd-supply = <&v3v3>;
+
+        stmfx_pinctrl: pinctrl {
+          compatible = "st,stmfx-0300-pinctrl";
+          #gpio-cells = <2>;
+          #interrupt-cells = <2>;
+          gpio-controller;
+          interrupt-controller;
+          gpio-ranges = <&stmfx_pinctrl 0 0 24>;
+
+          joystick_pins: joystick-pins {
+            pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
+            drive-push-pull;
+            bias-pull-up;
+          };
+        };
+      };
+    };
+...
index dd995d7..305123e 100644 (file)
@@ -113,8 +113,8 @@ properties:
             maxItems: 1
 
           st,mask-reset:
-            description: mask reset for this regulator,
-                         the regulator configuration is maintained during pmic reset.
+            description: mask reset for this regulator, the regulator configuration
+              is maintained during pmic reset.
             $ref: /schemas/types.yaml#/definitions/flag
 
           regulator-name: true
@@ -135,8 +135,8 @@ properties:
             maxItems: 1
 
           st,mask-reset:
-            description: mask reset for this regulator,
-                         the regulator configuration is maintained during pmic reset.
+            description: mask reset for this regulator, the regulator configuration
+              is maintained during pmic reset.
             $ref: /schemas/types.yaml#/definitions/flag
 
           regulator-name: true
@@ -154,8 +154,8 @@ properties:
             maxItems: 1
 
           st,mask-reset:
-            description: mask reset for this regulator,
-                         the regulator configuration is maintained during pmic reset.
+            description: mask reset for this regulator, the regulator configuration
+              is maintained during pmic reset.
             $ref: /schemas/types.yaml#/definitions/flag
 
           regulator-name: true
@@ -172,8 +172,8 @@ properties:
             maxItems: 1
 
           st,mask-reset:
-            description: mask reset for this regulator,
-                         the regulator configuration is maintained during pmic reset.
+            description: mask reset for this regulator, the regulator configuration
+              is maintained during pmic reset.
             $ref: /schemas/types.yaml#/definitions/flag
 
           regulator-name: true
@@ -198,8 +198,8 @@ properties:
             maxItems: 1
 
           st,mask-reset:
-            description: mask reset for this regulator,
-                         the regulator configuration is maintained during pmic reset.
+            description: mask reset for this regulator, the regulator configuration
+              is maintained during pmic reset.
             $ref: /schemas/types.yaml#/definitions/flag
 
           regulator-name: true
@@ -220,8 +220,8 @@ properties:
             maxItems: 1
 
           st,mask-reset:
-            description: mask reset for this regulator,
-                         the regulator configuration is maintained during pmic reset.
+            description: mask reset for this regulator, the regulator configuration
+              is maintained during pmic reset.
             $ref: /schemas/types.yaml#/definitions/flag
 
           regulator-name: true
diff --git a/Documentation/devicetree/bindings/mfd/stmfx.txt b/Documentation/devicetree/bindings/mfd/stmfx.txt
deleted file mode 100644 (file)
index f0c2f7f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-STMicroelectonics Multi-Function eXpander (STMFX) Core bindings
-
-ST Multi-Function eXpander (STMFX) is a slave controller using I2C for
-communication with the main MCU. Its main features are GPIO expansion, main
-MCU IDD measurement (IDD is the amount of current that flows through VDD) and
-resistive touchscreen controller.
-
-Required properties:
-- compatible: should be "st,stmfx-0300".
-- reg: I2C slave address of the device.
-- interrupts: interrupt specifier triggered by MFX_IRQ_OUT signal.
-  Please refer to ../interrupt-controller/interrupt.txt
-
-Optional properties:
-- drive-open-drain: configure MFX_IRQ_OUT as open drain.
-- vdd-supply: phandle of the regulator supplying STMFX.
-
-Example:
-
-       stmfx: stmfx@42 {
-               compatible = "st,stmfx-0300";
-               reg = <0x42>;
-               interrupts = <8 IRQ_TYPE_EDGE_RISING>;
-               interrupt-parent = <&gpioi>;
-               vdd-supply = <&v3v3>;
-       };
-
-Please refer to ../pinctrl/pinctrl-stmfx.txt for STMFX GPIO expander function bindings.
index 03d0a23..c8fd5d3 100644 (file)
@@ -24,12 +24,11 @@ maintainers:
 
 properties:
   compatible:
-    anyOf:
-      - items:
-        - enum:
-           - ti,j721e-system-controller
-        - const: syscon
-        - const: simple-mfd
+    items:
+      - enum:
+          - ti,j721e-system-controller
+      - const: syscon
+      - const: simple-mfd
 
   "#address-cells":
     const: 1
index 56f244b..c2f9302 100644 (file)
@@ -26,7 +26,7 @@ Optional node:
 Example:
 /*
  * Integrated Power Management Chip
- * http://www.ti.com/lit/ds/symlink/twl6030.pdf
+ * https://www.ti.com/lit/ds/symlink/twl6030.pdf
  */
 twl@48 {
     compatible = "ti,twl6030";
index 4c0106c..9e762d4 100644 (file)
@@ -73,13 +73,13 @@ allOf:
       required:
         - DBVDD3-supply
   - if:
-     properties:
-       compatible:
-         contains:
-           enum:
-             - cirrus,cs47l24
-             - wlf,wm1831
-             - wlf,wm8997
+      properties:
+        compatible:
+          contains:
+            enum:
+              - cirrus,cs47l24
+              - wlf,wm1831
+              - wlf,wm8997
     then:
       properties:
         SPKVDD-supply:
@@ -183,12 +183,12 @@ properties:
       clock supplied on MCLK2, recommended to be an always on 32k clock.
     oneOf:
       - items:
-        - const: mclk1
+          - const: mclk1
       - items:
-        - const: mclk2
+          - const: mclk2
       - items:
-        - const: mclk1
-        - const: mclk2
+          - const: mclk1
+          - const: mclk2
 
   reset-gpios:
     maxItems: 1
index 7a386a5..0cd74c3 100644 (file)
@@ -21,9 +21,9 @@ properties:
   compatible:
     items:
       - enum:
-        - amlogic,meson8-sdhc
-        - amlogic,meson8b-sdhc
-        - amlogic,meson8m2-sdhc
+          - amlogic,meson8-sdhc
+          - amlogic,meson8b-sdhc
+          - amlogic,meson8m2-sdhc
       - const: amlogic,meson-mx-sdhc
 
   reg:
index e60bfe9..9b63df1 100644 (file)
@@ -16,14 +16,14 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4740-mmc
-        - ingenic,jz4725b-mmc
-        - ingenic,jz4760-mmc
-        - ingenic,jz4780-mmc
-        - ingenic,x1000-mmc
+          - ingenic,jz4740-mmc
+          - ingenic,jz4725b-mmc
+          - ingenic,jz4760-mmc
+          - ingenic,jz4780-mmc
+          - ingenic,x1000-mmc
       - items:
-        - const: ingenic,jz4770-mmc
-        - const: ingenic,jz4760-mmc
+          - const: ingenic,jz4770-mmc
+          - const: ingenic,jz4760-mmc
 
   reg:
     maxItems: 1
index e5dbc20..b4c3fd4 100644 (file)
@@ -130,9 +130,9 @@ then:
   required:
     - clock-names
   description:
-     The internal card detection logic that exists in these controllers is
-     sectioned off to be run by a separate second clock source to allow
-     the main core clock to be turned off to save power.
+    The internal card detection logic that exists in these controllers is
+    sectioned off to be run by a separate second clock source to allow
+    the main core clock to be turned off to save power.
 
 unevaluatedProperties: false
 
index cb9794e..b328769 100644 (file)
@@ -14,12 +14,10 @@ maintainers:
 
 properties:
   compatible:
-    oneOf:
-      - items:
-        - enum:
+    items:
+      - enum:
           - xlnx,zynqmp-nand-controller
-        - enum:
-          - arasan,nfc-v3p10
+      - const: arasan,nfc-v3p10
 
   reg:
     maxItems: 1
index 354cb63..3201372 100644 (file)
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/mtd/gpmi-nand.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title:  Freescale General-Purpose Media Interface (GPMI) binding
+title: Freescale General-Purpose Media Interface (GPMI) binding
 
 maintainers:
   - Han Xu <han.xu@nxp.com>
index ee4d1d0..73b86f2 100644 (file)
@@ -4,7 +4,7 @@
 $id: http://devicetree.org/schemas/mtd/mxc-nand.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
-title:  Freescale's mxc_nand binding
+title: Freescale's mxc_nand binding
 
 maintainers:
   - Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
index 6ae7de1..28a08ff 100644 (file)
@@ -42,7 +42,7 @@ patternProperties:
         const: 512
 
       nand-ecc-strength:
-        enum: [1, 4 ,8 ]
+        enum: [1, 4, 8]
 
 allOf:
   - $ref: "nand-controller.yaml#"
index faea214..6a1ec50 100644 (file)
@@ -85,8 +85,8 @@ patternProperties:
 
 oneOf:
   - required:
-    - ports
+      - ports
   - required:
-    - ethernet-ports
+      - ethernet-ports
 
 ...
index a356127..8594f11 100644 (file)
@@ -43,7 +43,7 @@ description:
 
 properties:
   compatible:
-      const: "qcom,sdm845-ipa"
+    const: "qcom,sdm845-ipa"
 
   reg:
     items:
@@ -64,7 +64,7 @@ properties:
     maxItems: 1
 
   clock-names:
-      const: core
+    const: core
 
   interrupts:
     items:
@@ -96,8 +96,8 @@ properties:
     $ref: /schemas/types.yaml#/definitions/phandle-array
     description: State bits used in by the AP to signal the modem.
     items:
-    - description: Whether the "ipa-clock-enabled" state bit is valid
-    - description: Whether the IPA clock is enabled (if valid)
+      - description: Whether the "ipa-clock-enabled" state bit is valid
+      - description: Whether the IPA clock is enabled (if valid)
 
   qcom,smem-state-names:
     $ref: /schemas/types.yaml#/definitions/string-array
@@ -140,9 +140,9 @@ required:
 
 oneOf:
   - required:
-    - modem-init
+      - modem-init
   - required:
-    - memory-region
+      - memory-region
 
 examples:
   - |
index 7d84a86..cbacc04 100644 (file)
@@ -46,10 +46,10 @@ properties:
   clock-names:
     oneOf:
       - items:          # for Pro4
-        - const: gio
-        - const: ether
-        - const: ether-gb
-        - const: ether-phy
+          - const: gio
+          - const: ether
+          - const: ether-gb
+          - const: ether-phy
       - const: ether    # for others
 
   resets:
@@ -59,8 +59,8 @@ properties:
   reset-names:
     oneOf:
       - items:          # for Pro4
-        - const: gio
-        - const: ether
+          - const: gio
+          - const: ether
       - const: ether    # for others
 
   socionext,syscon-phy-mode:
index fafa34c..e5dff66 100644 (file)
@@ -48,11 +48,11 @@ properties:
     minItems: 3
     maxItems: 5
     items:
-        - description: GMAC main clock
-        - description: MAC TX clock
-        - description: MAC RX clock
-        - description: For MPU family, used for power mode
-        - description: For MPU family, used for PHY without quartz
+      - description: GMAC main clock
+      - description: MAC TX clock
+      - description: MAC RX clock
+      - description: For MPU family, used for power mode
+      - description: For MPU family, used for PHY without quartz
 
   clock-names:
     minItems: 3
@@ -89,7 +89,7 @@ required:
   - st,syscon
 
 examples:
- - |
 - |
     #include <dt-bindings/interrupt-controller/arm-gic.h>
     #include <dt-bindings/clock/stm32mp1-clks.h>
     #include <dt-bindings/reset/stm32mp1-resets.h>
index 3ea0e12..dadeb8f 100644 (file)
@@ -35,7 +35,7 @@ properties:
   reg:
     maxItems: 1
     description:
-       The physical base address and size of full the CPSW module IO range
+      The physical base address and size of full the CPSW module IO range
 
   '#address-cells':
     const: 1
@@ -85,36 +85,36 @@ properties:
 
     patternProperties:
       "^port@[0-9]+$":
-          type: object
-          description: CPSW external ports
-
-          allOf:
-            - $ref: ethernet-controller.yaml#
-
-          properties:
-            reg:
-              items:
-                - enum: [1, 2]
-              description: CPSW port number
-
-            phys:
-              maxItems: 1
-              description:  phandle on phy-gmii-sel PHY
-
-            label:
-              description: label associated with this port
-
-            ti,dual-emac-pvid:
-              $ref: /schemas/types.yaml#/definitions/uint32
-              minimum: 1
-              maximum: 1024
-              description:
-                Specifies default PORT VID to be used to segregate
-                ports. Default value - CPSW port number.
-
-          required:
-            - reg
-            - phys
+        type: object
+        description: CPSW external ports
+
+        allOf:
+          - $ref: ethernet-controller.yaml#
+
+        properties:
+          reg:
+            items:
+              - enum: [1, 2]
+            description: CPSW port number
+
+          phys:
+            maxItems: 1
+            description: phandle on phy-gmii-sel PHY
+
+          label:
+            description: label associated with this port
+
+          ti,dual-emac-pvid:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            minimum: 1
+            maximum: 1024
+            description:
+              Specifies default PORT VID to be used to segregate
+              ports. Default value - CPSW port number.
+
+        required:
+          - reg
+          - phys
 
   cpts:
     type: object
index 1745793..227270c 100644 (file)
@@ -55,7 +55,7 @@ properties:
   reg:
     maxItems: 1
     description:
-       The physical base address and size of full the CPSW2G NUSS IO range
+      The physical base address and size of full the CPSW2G NUSS IO range
 
   reg-names:
     items:
@@ -100,38 +100,38 @@ properties:
 
     patternProperties:
       port@1:
-       type: object
-       description: CPSW2G NUSS external ports
-
-       $ref: ethernet-controller.yaml#
-
-       properties:
-         reg:
-           items:
-             - const: 1
-           description: CPSW port number
-
-         phys:
-           maxItems: 1
-           description:  phandle on phy-gmii-sel PHY
-
-         label:
-           description: label associated with this port
-
-         ti,mac-only:
-           $ref: /schemas/types.yaml#definitions/flag
-           description:
-             Specifies the port works in mac-only mode.
-
-         ti,syscon-efuse:
-           $ref: /schemas/types.yaml#definitions/phandle-array
-           description:
-             Phandle to the system control device node which provides access
-             to efuse IO range with MAC addresses
-
-       required:
-         - reg
-         - phys
+        type: object
+        description: CPSW2G NUSS external ports
+
+        $ref: ethernet-controller.yaml#
+
+        properties:
+          reg:
+            items:
+              - const: 1
+            description: CPSW port number
+
+          phys:
+            maxItems: 1
+            description: phandle on phy-gmii-sel PHY
+
+          label:
+            description: label associated with this port
+
+          ti,mac-only:
+            $ref: /schemas/types.yaml#definitions/flag
+            description:
+              Specifies the port works in mac-only mode.
+
+          ti,syscon-efuse:
+            $ref: /schemas/types.yaml#definitions/phandle-array
+            description:
+              Phandle to the system control device node which provides access
+              to efuse IO range with MAC addresses
+
+        required:
+          - reg
+          - phys
 
     additionalProperties: false
 
index fe9c7df..1c9d7f0 100644 (file)
@@ -21,18 +21,18 @@ properties:
   compatible:
     items:
       - enum:
-        - fsl,imx6q-ocotp
-        - fsl,imx6sl-ocotp
-        - fsl,imx6sx-ocotp
-        - fsl,imx6ul-ocotp
-        - fsl,imx6ull-ocotp
-        - fsl,imx7d-ocotp
-        - fsl,imx6sll-ocotp
-        - fsl,imx7ulp-ocotp
-        - fsl,imx8mq-ocotp
-        - fsl,imx8mm-ocotp
-        - fsl,imx8mn-ocotp
-        - fsl,imx8mp-ocotp
+          - fsl,imx6q-ocotp
+          - fsl,imx6sl-ocotp
+          - fsl,imx6sx-ocotp
+          - fsl,imx6ul-ocotp
+          - fsl,imx6ull-ocotp
+          - fsl,imx7d-ocotp
+          - fsl,imx6sll-ocotp
+          - fsl,imx7ulp-ocotp
+          - fsl,imx8mq-ocotp
+          - fsl,imx8mm-ocotp
+          - fsl,imx8mn-ocotp
+          - fsl,imx8mp-ocotp
       - const: syscon
 
   reg:
index d10a0cf..59aca6d 100644 (file)
@@ -46,8 +46,8 @@ properties:
     const: 1
 
 required:
-   - compatible
-   - reg
+  - compatible
+  - reg
 
 examples:
   - |
index cfe25cf..b3c3d0c 100644 (file)
@@ -31,8 +31,7 @@ properties:
   ti,syscon-pcie-ctrl:
     description: Phandle to the SYSCON entry required for configuring PCIe mode
                  and link speed.
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   power-domains:
     maxItems: 1
index d7b6048..8200ba0 100644 (file)
@@ -31,8 +31,7 @@ properties:
   ti,syscon-pcie-ctrl:
     description: Phandle to the SYSCON entry required for configuring PCIe mode
       and link speed.
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   power-domains:
     maxItems: 1
index 9e32cb4..0d2557b 100644 (file)
@@ -37,9 +37,9 @@ properties:
     const: 0
 
   phy-supply:
-     description:
-       Phandle to a regulator that provides power to the PHY. This
-       regulator will be managed during the PHY power on/off sequence.
+    description:
+      Phandle to a regulator that provides power to the PHY. This
+      regulator will be managed during the PHY power on/off sequence.
 
 required:
   - compatible
index cb71561..fb29ad8 100644 (file)
@@ -100,9 +100,9 @@ properties:
           - const: linestate
           - const: otg-mux
           - items:
-            - const: otg-bvalid
-            - const: otg-id
-            - const: linestate
+              - const: otg-bvalid
+              - const: otg-id
+              - const: linestate
 
       phy-supply:
         description:
index e4cd4a1..185cdea 100644 (file)
@@ -37,7 +37,7 @@ properties:
       - description: Address and length of PHY's common serdes block.
 
   "#clock-cells":
-     enum: [ 1, 2 ]
+    enum: [ 1, 2 ]
 
   "#address-cells":
     enum: [ 1, 2 ]
@@ -65,16 +65,15 @@ properties:
 
   vdda-phy-supply:
     description:
-        Phandle to a regulator supply to PHY core block.
+      Phandle to a regulator supply to PHY core block.
 
   vdda-pll-supply:
     description:
-        Phandle to 1.8V regulator supply to PHY refclk pll block.
+      Phandle to 1.8V regulator supply to PHY refclk pll block.
 
   vddp-ref-clk-supply:
     description:
-        Phandle to a regulator supply to any specific refclk
-        pll block.
+      Phandle to a regulator supply to any specific refclk pll block.
 
 #Required nodes:
 patternProperties:
@@ -184,8 +183,8 @@ allOf:
             - description: phy common block reset.
         reset-names:
           items:
-             - const: phy
-             - const: common
+            - const: phy
+            - const: common
   - if:
       properties:
         compatible:
index 6e24875..ef8ae9f 100644 (file)
@@ -26,7 +26,7 @@ properties:
       - const: dp_com
 
   "#clock-cells":
-     enum: [ 1, 2 ]
+    enum: [ 1, 2 ]
 
   "#address-cells":
     enum: [ 1, 2 ]
@@ -62,16 +62,15 @@ properties:
 
   vdda-phy-supply:
     description:
-        Phandle to a regulator supply to PHY core block.
+      Phandle to a regulator supply to PHY core block.
 
   vdda-pll-supply:
     description:
-        Phandle to 1.8V regulator supply to PHY refclk pll block.
+      Phandle to 1.8V regulator supply to PHY refclk pll block.
 
   vddp-ref-clk-supply:
     description:
-        Phandle to a regulator supply to any specific refclk
-        pll block.
+      Phandle to a regulator supply to any specific refclk pll block.
 
 #Required nodes:
 patternProperties:
index 9ba62dc..ccda928 100644 (file)
@@ -17,15 +17,15 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - qcom,ipq8074-qusb2-phy
-          - qcom,msm8996-qusb2-phy
-          - qcom,msm8998-qusb2-phy
+          - enum:
+              - qcom,ipq8074-qusb2-phy
+              - qcom,msm8996-qusb2-phy
+              - qcom,msm8998-qusb2-phy
       - items:
-        - enum:
-          - qcom,sc7180-qusb2-phy
-          - qcom,sdm845-qusb2-phy
-        - const: qcom,qusb2-v2-phy
+          - enum:
+              - qcom,sc7180-qusb2-phy
+              - qcom,sdm845-qusb2-phy
+          - const: qcom,qusb2-v2-phy
   reg:
     maxItems: 1
 
@@ -49,12 +49,12 @@ properties:
       - const: iface
 
   vdda-pll-supply:
-     description:
-       Phandle to 1.8V regulator supply to PHY refclk pll block.
+    description:
+      Phandle to 1.8V regulator supply to PHY refclk pll block.
 
   vdda-phy-dpdm-supply:
-     description:
-       Phandle to 3.1V regulator supply to Dp/Dm port signals.
+    description:
+      Phandle to 3.1V regulator supply to Dp/Dm port signals.
 
   resets:
     maxItems: 1
@@ -64,12 +64,12 @@ properties:
   nvmem-cells:
     maxItems: 1
     description:
-        Phandle to nvmem cell that contains 'HS Tx trim'
-        tuning parameter value for qusb2 phy.
+      Phandle to nvmem cell that contains 'HS Tx trim'
+      tuning parameter value for qusb2 phy.
 
   qcom,tcsr-syscon:
     description:
-        Phandle to TCSR syscon register region.
+      Phandle to TCSR syscon register region.
     $ref: /schemas/types.yaml#/definitions/phandle
 
 if:
index 86f4909..a06831f 100644 (file)
@@ -33,8 +33,8 @@ properties:
   clock-names:
     oneOf:
       - items:            # for Pro5
-        - const: gio
-        - const: link
+          - const: gio
+          - const: link
       - const: link       # for others
 
   resets:
@@ -44,8 +44,8 @@ properties:
   reset-names:
     oneOf:
       - items:            # for Pro5
-        - const: gio
-        - const: link
+          - const: gio
+          - const: link
       - const: link       # for others
 
   socionext,syscon:
index c871d46..6fa5caa 100644 (file)
@@ -37,12 +37,12 @@ properties:
     oneOf:
       - const: link          # for PXs2
       - items:               # for PXs3 with phy-ext
-        - const: link
-        - const: phy
-        - const: phy-ext
+          - const: link
+          - const: phy
+          - const: phy-ext
       - items:               # for others
-        - const: link
-        - const: phy
+          - const: link
+          - const: phy
 
   resets:
     maxItems: 2
index edff2c9..9d46715 100644 (file)
@@ -37,15 +37,15 @@ properties:
   clock-names:
     oneOf:
       - items:             # for Pro4, Pro5
-        - const: gio
-        - const: link
+          - const: gio
+          - const: link
       - items:             # for PXs3 with phy-ext
-        - const: link
-        - const: phy
-        - const: phy-ext
+          - const: link
+          - const: phy
+          - const: phy-ext
       - items:             # for others
-        - const: link
-        - const: phy
+          - const: link
+          - const: phy
 
   resets:
     maxItems: 2
@@ -53,11 +53,11 @@ properties:
   reset-names:
     oneOf:
       - items:              # for Pro4,Pro5
-        - const: gio
-        - const: link
+          - const: gio
+          - const: link
       - items:              # for others
-        - const: link
-        - const: phy
+          - const: link
+          - const: phy
 
   vbus-supply:
     description: A phandle to the regulator for USB VBUS
index 3f913d6..5ffc95c 100644 (file)
@@ -203,7 +203,8 @@ examples:
            };
 
            refclk-dig {
-                  clocks = <&k3_clks 292 11>, <&k3_clks 292 0>, <&dummy_cmn_refclk>, <&dummy_cmn_refclk1>;
+                  clocks = <&k3_clks 292 11>, <&k3_clks 292 0>, 
+                          <&dummy_cmn_refclk>, <&dummy_cmn_refclk1>;
                   #clock-cells = <0>;
                   assigned-clocks = <&wiz0_refclk_dig>;
                   assigned-clock-parents = <&k3_clks 292 11>;
index 017d959..54631dc 100644 (file)
@@ -34,22 +34,22 @@ patternProperties:
       patternProperties:
         "^function|groups$":
           $ref: "/schemas/types.yaml#/definitions/string"
-          enum: [ACPI, ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15,
-            ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, DDCCLK, DDCDAT,
-            EXTRST, FLACK, FLBUSY, FLWP, GPID, GPID0, GPID2, GPID4, GPID6, GPIE0,
-            GPIE2, GPIE4, GPIE6, I2C10, I2C11, I2C12, I2C13, I2C14, I2C3, I2C4,
-            I2C5, I2C6, I2C7, I2C8, I2C9, LPCPD, LPCPME, LPCRST, LPCSMI, MAC1LINK,
-            MAC2LINK, MDIO1, MDIO2, NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2,
-            NDCD3, NDCD4, NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4,
-            NDTS4, NRI1, NRI2, NRI3, NRI4, NRTS1, NRTS2, NRTS3, OSCCLK, PWM0,
-            PWM1, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, RGMII1, RGMII2, RMII1,
-            RMII2, ROM16, ROM8, ROMCS1, ROMCS2, ROMCS3, ROMCS4, RXD1, RXD2, RXD3,
-            RXD4, SALT1, SALT2, SALT3, SALT4, SD1, SD2, SGPMCK, SGPMI, SGPMLD,
-            SGPMO, SGPSCK, SGPSI0, SGPSI1, SGPSLD, SIOONCTRL, SIOPBI, SIOPBO,
-            SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1DEBUG, SPI1PASSTHRU,
-            SPICS1, TIMER3, TIMER4, TIMER5, TIMER6, TIMER7, TIMER8, TXD1, TXD2,
-            TXD3, TXD4, UART6, USB11D1, USB11H2, USB2D1, USB2H1, USBCKI, VGABIOS_ROM,
-            VGAHS, VGAVS, VPI18, VPI24, VPI30, VPO12, VPO24, WDTRST1, WDTRST2]
+          enum: [ ACPI, ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15,
+                  ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, DDCCLK, DDCDAT,
+                  EXTRST, FLACK, FLBUSY, FLWP, GPID, GPID0, GPID2, GPID4, GPID6, GPIE0,
+                  GPIE2, GPIE4, GPIE6, I2C10, I2C11, I2C12, I2C13, I2C14, I2C3, I2C4,
+                  I2C5, I2C6, I2C7, I2C8, I2C9, LPCPD, LPCPME, LPCRST, LPCSMI, MAC1LINK,
+                  MAC2LINK, MDIO1, MDIO2, NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2,
+                  NDCD3, NDCD4, NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4,
+                  NDTS4, NRI1, NRI2, NRI3, NRI4, NRTS1, NRTS2, NRTS3, OSCCLK, PWM0,
+                  PWM1, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, RGMII1, RGMII2, RMII1,
+                  RMII2, ROM16, ROM8, ROMCS1, ROMCS2, ROMCS3, ROMCS4, RXD1, RXD2, RXD3,
+                  RXD4, SALT1, SALT2, SALT3, SALT4, SD1, SD2, SGPMCK, SGPMI, SGPMLD,
+                  SGPMO, SGPSCK, SGPSI0, SGPSI1, SGPSLD, SIOONCTRL, SIOPBI, SIOPBO,
+                  SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1DEBUG, SPI1PASSTHRU,
+                  SPICS1, TIMER3, TIMER4, TIMER5, TIMER6, TIMER7, TIMER8, TXD1, TXD2,
+                  TXD3, TXD4, UART6, USB11D1, USB11H2, USB2D1, USB2H1, USBCKI, VGABIOS_ROM,
+                  VGAHS, VGAVS, VPI18, VPI24, VPI30, VPO12, VPO24, WDTRST1, WDTRST2]
 
 required:
   - compatible
index c643d6d..a90c0fe 100644 (file)
@@ -43,24 +43,24 @@ patternProperties:
       patternProperties:
         "^function|groups$":
           $ref: "/schemas/types.yaml#/definitions/string"
-          enum: [ACPI, ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15,
-            ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, DDCCLK, DDCDAT,
-            ESPI, FWSPICS1, FWSPICS2, GPID0, GPID2, GPID4, GPID6, GPIE0, GPIE2,
-            GPIE4, GPIE6, I2C10, I2C11, I2C12, I2C13, I2C14, I2C3, I2C4, I2C5,
-            I2C6, I2C7, I2C8, I2C9, LAD0, LAD1, LAD2, LAD3, LCLK, LFRAME, LPCHC,
-            LPCPD, LPCPLUS, LPCPME, LPCRST, LPCSMI, LSIRQ, MAC1LINK, MAC2LINK,
-            MDIO1, MDIO2, NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4,
-            NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1, NRI2,
-            NRI3, NRI4, NRTS1, NRTS2, NRTS3, NRTS4, OSCCLK, PEWAKE, PNOR, PWM0,
-            PWM1, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, RGMII1, RGMII2, RMII1,
-            RMII2, RXD1, RXD2, RXD3, RXD4, SALT1, SALT10, SALT11, SALT12, SALT13,
-            SALT14, SALT2, SALT3, SALT4, SALT5, SALT6, SALT7, SALT8, SALT9, SCL1,
-            SCL2, SD1, SD2, SDA1, SDA2, SGPS1, SGPS2, SIOONCTRL, SIOPBI, SIOPBO,
-            SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1CS1, SPI1DEBUG,
-            SPI1PASSTHRU, SPI2CK, SPI2CS0, SPI2CS1, SPI2MISO, SPI2MOSI, TIMER3,
-            TIMER4, TIMER5, TIMER6, TIMER7, TIMER8, TXD1, TXD2, TXD3, TXD4, UART6,
-            USB11BHID, USB2AD, USB2AH, USB2BD, USB2BH, USBCKI, VGABIOSROM, VGAHS,
-            VGAVS, VPI24, VPO, WDTRST1, WDTRST2]
+          enum: [ ACPI, ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15,
+                  ADC2, ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, DDCCLK, DDCDAT,
+                  ESPI, FWSPICS1, FWSPICS2, GPID0, GPID2, GPID4, GPID6, GPIE0, GPIE2,
+                  GPIE4, GPIE6, I2C10, I2C11, I2C12, I2C13, I2C14, I2C3, I2C4, I2C5,
+                  I2C6, I2C7, I2C8, I2C9, LAD0, LAD1, LAD2, LAD3, LCLK, LFRAME, LPCHC,
+                  LPCPD, LPCPLUS, LPCPME, LPCRST, LPCSMI, LSIRQ, MAC1LINK, MAC2LINK,
+                  MDIO1, MDIO2, NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4,
+                  NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1, NRI2,
+                  NRI3, NRI4, NRTS1, NRTS2, NRTS3, NRTS4, OSCCLK, PEWAKE, PNOR, PWM0,
+                  PWM1, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, RGMII1, RGMII2, RMII1,
+                  RMII2, RXD1, RXD2, RXD3, RXD4, SALT1, SALT10, SALT11, SALT12, SALT13,
+                  SALT14, SALT2, SALT3, SALT4, SALT5, SALT6, SALT7, SALT8, SALT9, SCL1,
+                  SCL2, SD1, SD2, SDA1, SDA2, SGPS1, SGPS2, SIOONCTRL, SIOPBI, SIOPBO,
+                  SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1CS1, SPI1DEBUG,
+                  SPI1PASSTHRU, SPI2CK, SPI2CS0, SPI2CS1, SPI2MISO, SPI2MOSI, TIMER3,
+                  TIMER4, TIMER5, TIMER6, TIMER7, TIMER8, TXD1, TXD2, TXD3, TXD4, UART6,
+                  USB11BHID, USB2AD, USB2AH, USB2BD, USB2BH, USBCKI, VGABIOSROM, VGAHS,
+                  VGAVS, VPI24, VPO, WDTRST1, WDTRST2]
 
 required:
   - compatible
index 1506726..c78ab7e 100644 (file)
@@ -31,57 +31,57 @@ patternProperties:
       properties:
         function:
           $ref: "/schemas/types.yaml#/definitions/string"
-          enum: [ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15, ADC2,
-            ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, EMMC, ESPI, ESPIALT,
-            FSI1, FSI2, FWSPIABR, FWSPID, FWSPIWP, GPIT0, GPIT1, GPIT2, GPIT3,
-            GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1, GPIU2, GPIU3, GPIU4, GPIU5,
-            GPIU6, GPIU7, I2C1, I2C10, I2C11, I2C12, I2C13, I2C14, I2C15, I2C16,
-            I2C2, I2C3, I2C4, I2C5, I2C6, I2C7, I2C8, I2C9, I3C3, I3C4, I3C5,
-            I3C6, JTAGM, LHPD, LHSIRQ, LPC, LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ,
-            MACLINK1, MACLINK2, MACLINK3, MACLINK4, MDIO1, MDIO2, MDIO3, MDIO4,
-            NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4, NDSR1, NDSR2,
-            NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1, NRI2, NRI3, NRI4,
-            NRTS1, NRTS2, NRTS3, NRTS4, OSCCLK, PEWAKE, PWM0, PWM1, PWM10, PWM11,
-            PWM12, PWM13, PWM14, PWM15, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, PWM8,
-            PWM9, RGMII1, RGMII2, RGMII3, RGMII4, RMII1, RMII2, RMII3, RMII4,
-            RXD1, RXD2, RXD3, RXD4, SALT1, SALT10, SALT11, SALT12, SALT13, SALT14,
-            SALT15, SALT16, SALT2, SALT3, SALT4, SALT5, SALT6, SALT7, SALT8,
-            SALT9, SD1, SD2, SGPM1, SGPS1, SIOONCTRL, SIOPBI, SIOPBO, SIOPWREQ,
-            SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1ABR, SPI1CS1, SPI1WP, SPI2,
-            SPI2CS1, SPI2CS2, TACH0, TACH1, TACH10, TACH11, TACH12, TACH13, TACH14,
-            TACH15, TACH2, TACH3, TACH4, TACH5, TACH6, TACH7, TACH8, TACH9, THRU0,
-            THRU1, THRU2, THRU3, TXD1, TXD2, TXD3, TXD4, UART10, UART11, UART12,
-            UART13, UART6, UART7, UART8, UART9, USBAD, USBADP, USB2AH, USB2AHP,
-            USB2BD, USB2BH, VB, VGAHS, VGAVS, WDTRST1, WDTRST2, WDTRST3, WDTRST4]
+          enum: [ ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15, ADC2,
+                  ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, EMMC, ESPI, ESPIALT,
+                  FSI1, FSI2, FWSPIABR, FWSPID, FWSPIWP, GPIT0, GPIT1, GPIT2, GPIT3,
+                  GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1, GPIU2, GPIU3, GPIU4, GPIU5,
+                  GPIU6, GPIU7, I2C1, I2C10, I2C11, I2C12, I2C13, I2C14, I2C15, I2C16,
+                  I2C2, I2C3, I2C4, I2C5, I2C6, I2C7, I2C8, I2C9, I3C3, I3C4, I3C5,
+                  I3C6, JTAGM, LHPD, LHSIRQ, LPC, LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ,
+                  MACLINK1, MACLINK2, MACLINK3, MACLINK4, MDIO1, MDIO2, MDIO3, MDIO4,
+                  NCTS1, NCTS2, NCTS3, NCTS4, NDCD1, NDCD2, NDCD3, NDCD4, NDSR1, NDSR2,
+                  NDSR3, NDSR4, NDTR1, NDTR2, NDTR3, NDTR4, NRI1, NRI2, NRI3, NRI4,
+                  NRTS1, NRTS2, NRTS3, NRTS4, OSCCLK, PEWAKE, PWM0, PWM1, PWM10, PWM11,
+                  PWM12, PWM13, PWM14, PWM15, PWM2, PWM3, PWM4, PWM5, PWM6, PWM7, PWM8,
+                  PWM9, RGMII1, RGMII2, RGMII3, RGMII4, RMII1, RMII2, RMII3, RMII4,
+                  RXD1, RXD2, RXD3, RXD4, SALT1, SALT10, SALT11, SALT12, SALT13, SALT14,
+                  SALT15, SALT16, SALT2, SALT3, SALT4, SALT5, SALT6, SALT7, SALT8,
+                  SALT9, SD1, SD2, SGPM1, SGPS1, SIOONCTRL, SIOPBI, SIOPBO, SIOPWREQ,
+                  SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1ABR, SPI1CS1, SPI1WP, SPI2,
+                  SPI2CS1, SPI2CS2, TACH0, TACH1, TACH10, TACH11, TACH12, TACH13, TACH14,
+                  TACH15, TACH2, TACH3, TACH4, TACH5, TACH6, TACH7, TACH8, TACH9, THRU0,
+                  THRU1, THRU2, THRU3, TXD1, TXD2, TXD3, TXD4, UART10, UART11, UART12,
+                  UART13, UART6, UART7, UART8, UART9, USBAD, USBADP, USB2AH, USB2AHP,
+                  USB2BD, USB2BH, VB, VGAHS, VGAVS, WDTRST1, WDTRST2, WDTRST3, WDTRST4 ]
 
         groups:
           $ref: "/schemas/types.yaml#/definitions/string"
-          enum: [ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15, ADC2,
-            ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, EMMCG1, EMMCG4,
-            EMMCG8, ESPI, ESPIALT, FSI1, FSI2, FWSPIABR, FWSPID, FWQSPID, FWSPIWP,
-            GPIT0, GPIT1, GPIT2, GPIT3, GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1,
-            GPIU2, GPIU3, GPIU4, GPIU5, GPIU6, GPIU7, HVI3C3, HVI3C4, I2C1, I2C10,
-            I2C11, I2C12, I2C13, I2C14, I2C15, I2C16, I2C2, I2C3, I2C4, I2C5,
-            I2C6, I2C7, I2C8, I2C9, I3C3, I3C4, I3C5, I3C6, JTAGM, LHPD, LHSIRQ,
-            LPC, LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ, MACLINK1, MACLINK2, MACLINK3,
-            MACLINK4, MDIO1, MDIO2, MDIO3, MDIO4, NCTS1, NCTS2, NCTS3, NCTS4,
-            NDCD1, NDCD2, NDCD3, NDCD4, NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2,
-            NDTR3, NDTR4, NRI1, NRI2, NRI3, NRI4, NRTS1, NRTS2, NRTS3, NRTS4,
-            OSCCLK, PEWAKE, PWM0, PWM1, PWM10G0, PWM10G1, PWM11G0, PWM11G1, PWM12G0,
-            PWM12G1, PWM13G0, PWM13G1, PWM14G0, PWM14G1, PWM15G0, PWM15G1, PWM2,
-            PWM3, PWM4, PWM5, PWM6, PWM7, PWM8G0, PWM8G1, PWM9G0, PWM9G1, QSPI1,
-            QSPI2, RGMII1, RGMII2, RGMII3, RGMII4, RMII1, RMII2, RMII3, RMII4,
-            RXD1, RXD2, RXD3, RXD4, SALT1, SALT10G0, SALT10G1, SALT11G0, SALT11G1,
-            SALT12G0, SALT12G1, SALT13G0, SALT13G1, SALT14G0, SALT14G1, SALT15G0,
-            SALT15G1, SALT16G0, SALT16G1, SALT2, SALT3, SALT4, SALT5, SALT6,
-            SALT7, SALT8, SALT9G0, SALT9G1, SD1, SD2, SD3, SGPM1, SGPS1, SIOONCTRL,
-            SIOPBI, SIOPBO, SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1ABR,
-            SPI1CS1, SPI1WP, SPI2, SPI2CS1, SPI2CS2, TACH0, TACH1, TACH10, TACH11,
-            TACH12, TACH13, TACH14, TACH15, TACH2, TACH3, TACH4, TACH5, TACH6,
-            TACH7, TACH8, TACH9, THRU0, THRU1, THRU2, THRU3, TXD1, TXD2, TXD3,
-            TXD4, UART10, UART11, UART12G0, UART12G1, UART13G0, UART13G1, UART6,
-            UART7, UART8, UART9, USBA, USBB, VB, VGAHS, VGAVS, WDTRST1, WDTRST2,
-            WDTRST3, WDTRST4]
+          enum: [ ADC0, ADC1, ADC10, ADC11, ADC12, ADC13, ADC14, ADC15, ADC2,
+                  ADC3, ADC4, ADC5, ADC6, ADC7, ADC8, ADC9, BMCINT, EMMCG1, EMMCG4,
+                  EMMCG8, ESPI, ESPIALT, FSI1, FSI2, FWSPIABR, FWSPID, FWQSPID, FWSPIWP,
+                  GPIT0, GPIT1, GPIT2, GPIT3, GPIT4, GPIT5, GPIT6, GPIT7, GPIU0, GPIU1,
+                  GPIU2, GPIU3, GPIU4, GPIU5, GPIU6, GPIU7, HVI3C3, HVI3C4, I2C1, I2C10,
+                  I2C11, I2C12, I2C13, I2C14, I2C15, I2C16, I2C2, I2C3, I2C4, I2C5,
+                  I2C6, I2C7, I2C8, I2C9, I3C3, I3C4, I3C5, I3C6, JTAGM, LHPD, LHSIRQ,
+                  LPC, LPCHC, LPCPD, LPCPME, LPCSMI, LSIRQ, MACLINK1, MACLINK2, MACLINK3,
+                  MACLINK4, MDIO1, MDIO2, MDIO3, MDIO4, NCTS1, NCTS2, NCTS3, NCTS4,
+                  NDCD1, NDCD2, NDCD3, NDCD4, NDSR1, NDSR2, NDSR3, NDSR4, NDTR1, NDTR2,
+                  NDTR3, NDTR4, NRI1, NRI2, NRI3, NRI4, NRTS1, NRTS2, NRTS3, NRTS4,
+                  OSCCLK, PEWAKE, PWM0, PWM1, PWM10G0, PWM10G1, PWM11G0, PWM11G1, PWM12G0,
+                  PWM12G1, PWM13G0, PWM13G1, PWM14G0, PWM14G1, PWM15G0, PWM15G1, PWM2,
+                  PWM3, PWM4, PWM5, PWM6, PWM7, PWM8G0, PWM8G1, PWM9G0, PWM9G1, QSPI1,
+                  QSPI2, RGMII1, RGMII2, RGMII3, RGMII4, RMII1, RMII2, RMII3, RMII4,
+                  RXD1, RXD2, RXD3, RXD4, SALT1, SALT10G0, SALT10G1, SALT11G0, SALT11G1,
+                  SALT12G0, SALT12G1, SALT13G0, SALT13G1, SALT14G0, SALT14G1, SALT15G0,
+                  SALT15G1, SALT16G0, SALT16G1, SALT2, SALT3, SALT4, SALT5, SALT6,
+                  SALT7, SALT8, SALT9G0, SALT9G1, SD1, SD2, SD3, SGPM1, SGPS1, SIOONCTRL,
+                  SIOPBI, SIOPBO, SIOPWREQ, SIOPWRGD, SIOS3, SIOS5, SIOSCI, SPI1, SPI1ABR,
+                  SPI1CS1, SPI1WP, SPI2, SPI2CS1, SPI2CS2, TACH0, TACH1, TACH10, TACH11,
+                  TACH12, TACH13, TACH14, TACH15, TACH2, TACH3, TACH4, TACH5, TACH6,
+                  TACH7, TACH8, TACH9, THRU0, THRU1, THRU2, THRU3, TXD1, TXD2, TXD3,
+                  TXD4, UART10, UART11, UART12G0, UART12G1, UART13G0, UART13G1, UART6,
+                  UART7, UART8, UART9, USBA, USBB, VB, VGAHS, VGAVS, WDTRST1, WDTRST2,
+                  WDTRST3, WDTRST4]
 
 required:
   - compatible
index 18163fb..44c04d1 100644 (file)
@@ -32,20 +32,20 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4740-pinctrl
-        - ingenic,jz4725b-pinctrl
-        - ingenic,jz4760-pinctrl
-        - ingenic,jz4770-pinctrl
-        - ingenic,jz4780-pinctrl
-        - ingenic,x1000-pinctrl
-        - ingenic,x1500-pinctrl
-        - ingenic,x1830-pinctrl
+          - ingenic,jz4740-pinctrl
+          - ingenic,jz4725b-pinctrl
+          - ingenic,jz4760-pinctrl
+          - ingenic,jz4770-pinctrl
+          - ingenic,jz4780-pinctrl
+          - ingenic,x1000-pinctrl
+          - ingenic,x1500-pinctrl
+          - ingenic,x1830-pinctrl
       - items:
-        - const: ingenic,jz4760b-pinctrl
-        - const: ingenic,jz4760-pinctrl
+          - const: ingenic,jz4760b-pinctrl
+          - const: ingenic,jz4760-pinctrl
       - items:
-        - const: ingenic,x1000e-pinctrl
-        - const: ingenic,x1000-pinctrl
+          - const: ingenic,x1000e-pinctrl
+          - const: ingenic,x1000-pinctrl
 
   reg:
     maxItems: 1
diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-stmfx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-stmfx.txt
deleted file mode 100644 (file)
index c1b4c18..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-STMicroelectronics Multi-Function eXpander (STMFX) GPIO expander bindings
-
-ST Multi-Function eXpander (STMFX) offers up to 24 GPIOs expansion.
-Please refer to ../mfd/stmfx.txt for STMFX Core bindings.
-
-Required properties:
-- compatible: should be "st,stmfx-0300-pinctrl".
-- #gpio-cells: should be <2>, the first cell is the GPIO number and the second
-  cell is the gpio flags in accordance with <dt-bindings/gpio/gpio.h>.
-- gpio-controller: marks the device as a GPIO controller.
-- #interrupt-cells: should be <2>, the first cell is the GPIO number and the
-  second cell is the interrupt flags in accordance with
-  <dt-bindings/interrupt-controller/irq.h>.
-- interrupt-controller: marks the device as an interrupt controller.
-- gpio-ranges: specifies the mapping between gpio controller and pin
-  controller pins. Check "Concerning gpio-ranges property" below.
-Please refer to ../gpio/gpio.txt.
-
-Please refer to pinctrl-bindings.txt for pin configuration.
-
-Required properties for pin configuration sub-nodes:
-- pins: list of pins to which the configuration applies.
-
-Optional properties for pin configuration sub-nodes (pinconf-generic ones):
-- bias-disable: disable any bias on the pin.
-- bias-pull-up: the pin will be pulled up.
-- bias-pull-pin-default: use the pin-default pull state.
-- bias-pull-down: the pin will be pulled down.
-- drive-open-drain: the pin will be driven with open drain.
-- drive-push-pull: the pin will be driven actively high and low.
-- output-high: the pin will be configured as an output driving high level.
-- output-low: the pin will be configured as an output driving low level.
-
-Note that STMFX pins[15:0] are called "gpio[15:0]", and STMFX pins[23:16] are
-called "agpio[7:0]". Example, to refer to pin 18 of STMFX, use "agpio2".
-
-Concerning gpio-ranges property:
-- if all STMFX pins[24:0] are available (no other STMFX function in use), you
-  should use gpio-ranges = <&stmfx_pinctrl 0 0 24>;
-- if agpio[3:0] are not available (STMFX Touchscreen function in use), you
-  should use gpio-ranges = <&stmfx_pinctrl 0 0 16>, <&stmfx_pinctrl 20 20 4>;
-- if agpio[7:4] are not available (STMFX IDD function in use), you
-  should use gpio-ranges = <&stmfx_pinctrl 0 0 20>;
-
-
-Example:
-
-       stmfx: stmfx@42 {
-               ...
-
-               stmfx_pinctrl: stmfx-pin-controller {
-                       compatible = "st,stmfx-0300-pinctrl";
-                       #gpio-cells = <2>;
-                       #interrupt-cells = <2>;
-                       gpio-controller;
-                       interrupt-controller;
-                       gpio-ranges = <&stmfx_pinctrl 0 0 24>;
-
-                       joystick_pins: joystick {
-                               pins = "gpio0", "gpio1", "gpio2", "gpio3", "gpio4";
-                               drive-push-pull;
-                               bias-pull-up;
-                       };
-               };
-       };
-
-Example of STMFX GPIO consumers:
-
-       joystick {
-               compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               pinctrl-0 = <&joystick_pins>;
-               pinctrl-names = "default";
-               button-0 {
-                       label = "JoySel";
-                       linux,code = <KEY_ENTER>;
-                       interrupt-parent = <&stmfx_pinctrl>;
-                       interrupts = <0 IRQ_TYPE_EDGE_RISING>;
-               };
-               button-1 {
-                       label = "JoyDown";
-                       linux,code = <KEY_DOWN>;
-                       interrupt-parent = <&stmfx_pinctrl>;
-                       interrupts = <1 IRQ_TYPE_EDGE_RISING>;
-               };
-               button-2 {
-                       label = "JoyLeft";
-                       linux,code = <KEY_LEFT>;
-                       interrupt-parent = <&stmfx_pinctrl>;
-                       interrupts = <2 IRQ_TYPE_EDGE_RISING>;
-               };
-               button-3 {
-                       label = "JoyRight";
-                       linux,code = <KEY_RIGHT>;
-                       interrupt-parent = <&stmfx_pinctrl>;
-                       interrupts = <3 IRQ_TYPE_EDGE_RISING>;
-               };
-               button-4 {
-                       label = "JoyUp";
-                       linux,code = <KEY_UP>;
-                       interrupt-parent = <&stmfx_pinctrl>;
-                       interrupts = <4 IRQ_TYPE_EDGE_RISING>;
-               };
-       };
-
-       leds {
-               compatible = "gpio-leds";
-               orange {
-                       gpios = <&stmfx_pinctrl 17 1>;
-               };
-
-               blue {
-                       gpios = <&stmfx_pinctrl 19 1>;
-               };
-       }
index b2de399..c64c932 100644 (file)
@@ -60,8 +60,8 @@ patternProperties:
           oneOf:
             - pattern: "^gpio([1-9]|[1-7][0-9]|80)$"
             - enum: [ sdc1_clk, sdc1_cmd, sdc1_data, sdc2_clk, sdc2_cmd,
-              sdc2_data, qdsd_cmd, qdsd_data0, qdsd_data1, qdsd_data2,
-              qdsd_data3 ]
+                      sdc2_data, qdsd_cmd, qdsd_data0, qdsd_data1, qdsd_data2,
+                      qdsd_data3 ]
         minItems: 1
         maxItems: 4
 
@@ -70,31 +70,31 @@ patternProperties:
           Specify the alternative function to be configured for the specified
           pins.
         enum: [ adsp_ext, alsp_int, atest_bbrx0, atest_bbrx1, atest_char,
-          atest_char0, atest_char1, atest_char2, atest_char3, atest_combodac,
-          atest_gpsadc0, atest_gpsadc1, atest_tsens, atest_wlan0,
-          atest_wlan1, backlight_en, bimc_dte0, bimc_dte1, blsp1_i2c,
-          blsp2_i2c, blsp3_i2c, blsp4_i2c, blsp5_i2c, blsp6_i2c,  blsp1_spi,
-          blsp1_spi_cs1, blsp1_spi_cs2, blsp1_spi_cs3, blsp2_spi,
-          blsp2_spi_cs1, blsp2_spi_cs2, blsp2_spi_cs3, blsp3_spi,
-          blsp3_spi_cs1, blsp3_spi_cs2, blsp3_spi_cs3, blsp4_spi, blsp5_spi,
-          blsp6_spi, blsp1_uart, blsp2_uart, blsp1_uim, blsp2_uim, cam1_rst,
-          cam1_standby, cam_mclk0, cam_mclk1, cci_async, cci_i2c, cci_timer0,
-          cci_timer1, cci_timer2, cdc_pdm0, codec_mad, dbg_out, display_5v,
-          dmic0_clk, dmic0_data, dsi_rst, ebi0_wrcdc, euro_us, ext_lpass,
-          flash_strobe, gcc_gp1_clk_a, gcc_gp1_clk_b, gcc_gp2_clk_a,
-          gcc_gp2_clk_b, gcc_gp3_clk_a, gcc_gp3_clk_b, gpio, gsm0_tx0,
-          gsm0_tx1, gsm1_tx0, gsm1_tx1, gyro_accl, kpsns0, kpsns1, kpsns2,
-          ldo_en, ldo_update, mag_int, mdp_vsync, modem_tsync, m_voc,
-          nav_pps, nav_tsync, pa_indicator, pbs0, pbs1, pbs2, pri_mi2s,
-          pri_mi2s_ws, prng_rosc, pwr_crypto_enabled_a, pwr_crypto_enabled_b,
-          pwr_modem_enabled_a,  pwr_modem_enabled_b, pwr_nav_enabled_a,
-          pwr_nav_enabled_b, qdss_ctitrig_in_a0, qdss_ctitrig_in_a1,
-          qdss_ctitrig_in_b0, qdss_ctitrig_in_b1, qdss_ctitrig_out_a0,
-          qdss_ctitrig_out_a1, qdss_ctitrig_out_b0, qdss_ctitrig_out_b1,
-          qdss_traceclk_a, qdss_traceclk_b, qdss_tracectl_a, qdss_tracectl_b,
-          qdss_tracedata_a, qdss_tracedata_b, reset_n, sd_card, sd_write,
-          sec_mi2s, smb_int, ssbi_wtr0, ssbi_wtr1, uim1, uim2, uim3,
-          uim_batt, wcss_bt, wcss_fm, wcss_wlan, webcam1_rst ]
+                atest_char0, atest_char1, atest_char2, atest_char3, atest_combodac,
+                atest_gpsadc0, atest_gpsadc1, atest_tsens, atest_wlan0,
+                atest_wlan1, backlight_en, bimc_dte0, bimc_dte1, blsp1_i2c,
+                blsp2_i2c, blsp3_i2c, blsp4_i2c, blsp5_i2c, blsp6_i2c, blsp1_spi,
+                blsp1_spi_cs1, blsp1_spi_cs2, blsp1_spi_cs3, blsp2_spi,
+                blsp2_spi_cs1, blsp2_spi_cs2, blsp2_spi_cs3, blsp3_spi,
+                blsp3_spi_cs1, blsp3_spi_cs2, blsp3_spi_cs3, blsp4_spi, blsp5_spi,
+                blsp6_spi, blsp1_uart, blsp2_uart, blsp1_uim, blsp2_uim, cam1_rst,
+                cam1_standby, cam_mclk0, cam_mclk1, cci_async, cci_i2c, cci_timer0,
+                cci_timer1, cci_timer2, cdc_pdm0, codec_mad, dbg_out, display_5v,
+                dmic0_clk, dmic0_data, dsi_rst, ebi0_wrcdc, euro_us, ext_lpass,
+                flash_strobe, gcc_gp1_clk_a, gcc_gp1_clk_b, gcc_gp2_clk_a,
+                gcc_gp2_clk_b, gcc_gp3_clk_a, gcc_gp3_clk_b, gpio, gsm0_tx0,
+                gsm0_tx1, gsm1_tx0, gsm1_tx1, gyro_accl, kpsns0, kpsns1, kpsns2,
+                ldo_en, ldo_update, mag_int, mdp_vsync, modem_tsync, m_voc,
+                nav_pps, nav_tsync, pa_indicator, pbs0, pbs1, pbs2, pri_mi2s,
+                pri_mi2s_ws, prng_rosc, pwr_crypto_enabled_a, pwr_crypto_enabled_b,
+                pwr_modem_enabled_a, pwr_modem_enabled_b, pwr_nav_enabled_a,
+                pwr_nav_enabled_b, qdss_ctitrig_in_a0, qdss_ctitrig_in_a1,
+                qdss_ctitrig_in_b0, qdss_ctitrig_in_b1, qdss_ctitrig_out_a0,
+                qdss_ctitrig_out_a1, qdss_ctitrig_out_b0, qdss_ctitrig_out_b1,
+                qdss_traceclk_a, qdss_traceclk_b, qdss_tracectl_a, qdss_tracectl_b,
+                qdss_tracedata_a, qdss_tracedata_b, reset_n, sd_card, sd_write,
+                sec_mi2s, smb_int, ssbi_wtr0, ssbi_wtr1, uim1, uim2, uim3,
+                uim_batt, wcss_bt, wcss_fm, wcss_wlan, webcam1_rst ]
 
       drive-strength:
         enum: [2, 4, 6, 8, 10, 12, 14, 16]
index 6dc3b52..8508c57 100644 (file)
@@ -76,22 +76,22 @@ patternProperties:
             pins.
 
           enum: [ aoss_cti, atest, audio_ref, cam_mclk, cci_async, cci_i2c,
-            cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4, cri_trng,
-            cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
-            ddr_pxi2, ddr_pxi3, dp_hot, dp_lcd, gcc_gp1, gcc_gp2, gcc_gp3, gpio,
-            ibi_i3c, jitter_bist, lpass_slimbus, mdp_vsync, mdp_vsync0,
-            mdp_vsync1, mdp_vsync2, mdp_vsync3, mi2s0_data0, mi2s0_data1,
-            mi2s0_sck, mi2s0_ws, mi2s1_data0, mi2s1_data1, mi2s1_sck, mi2s1_ws,
-            mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, pci_e0, pci_e1,
-            pci_e2, phase_flag, pll_bist, pll_bypassnl, pll_clk, pll_reset,
-            pri_mi2s, prng_rosc, qdss_cti, qdss_gpio, qspi0, qspi1, qspi2, qspi3,
-            qspi_clk, qspi_cs, qup0, qup1, qup10, qup11, qup12, qup13, qup14,
-            qup15, qup16, qup17, qup18, qup19, qup2, qup3, qup4, qup5, qup6,
-            qup7, qup8, qup9, qup_l4, qup_l5, qup_l6, sd_write, sdc40, sdc41,
-            sdc42, sdc43, sdc4_clk, sdc4_cmd, sec_mi2s, sp_cmu, tgu_ch0, tgu_ch1,
-            tgu_ch2, tgu_ch3, tsense_pwm1, tsense_pwm2, tsif0_clk, tsif0_data,
-            tsif0_en, tsif0_error, tsif0_sync, tsif1_clk, tsif1_data, tsif1_en,
-            tsif1_error, tsif1_sync, usb2phy_ac, usb_phy, vsense_trigger ]
+                  cci_timer0, cci_timer1, cci_timer2, cci_timer3, cci_timer4, cri_trng,
+                  cri_trng0, cri_trng1, dbg_out, ddr_bist, ddr_pxi0, ddr_pxi1,
+                  ddr_pxi2, ddr_pxi3, dp_hot, dp_lcd, gcc_gp1, gcc_gp2, gcc_gp3, gpio,
+                  ibi_i3c, jitter_bist, lpass_slimbus, mdp_vsync, mdp_vsync0,
+                  mdp_vsync1, mdp_vsync2, mdp_vsync3, mi2s0_data0, mi2s0_data1,
+                  mi2s0_sck, mi2s0_ws, mi2s1_data0, mi2s1_data1, mi2s1_sck, mi2s1_ws,
+                  mi2s2_data0, mi2s2_data1, mi2s2_sck, mi2s2_ws, pci_e0, pci_e1,
+                  pci_e2, phase_flag, pll_bist, pll_bypassnl, pll_clk, pll_reset,
+                  pri_mi2s, prng_rosc, qdss_cti, qdss_gpio, qspi0, qspi1, qspi2, qspi3,
+                  qspi_clk, qspi_cs, qup0, qup1, qup10, qup11, qup12, qup13, qup14,
+                  qup15, qup16, qup17, qup18, qup19, qup2, qup3, qup4, qup5, qup6,
+                  qup7, qup8, qup9, qup_l4, qup_l5, qup_l6, sd_write, sdc40, sdc41,
+                  sdc42, sdc43, sdc4_clk, sdc4_cmd, sec_mi2s, sp_cmu, tgu_ch0, tgu_ch1,
+                  tgu_ch2, tgu_ch3, tsense_pwm1, tsense_pwm2, tsif0_clk, tsif0_data,
+                  tsif0_en, tsif0_error, tsif0_sync, tsif1_clk, tsif1_data, tsif1_en,
+                  tsif1_error, tsif1_sync, usb2phy_ac, usb_phy, vsense_trigger ]
 
         drive-strength:
           enum: [2, 4, 6, 8, 10, 12, 14, 16]
index 0857cbe..7287754 100644 (file)
@@ -48,8 +48,8 @@ properties:
 
   st,package:
     description:
-     Indicates the SOC package used.
-     More details in include/dt-bindings/pinctrl/stm32-pinfunc.h
+      Indicates the SOC package used.
+      More details in include/dt-bindings/pinctrl/stm32-pinfunc.h
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [1, 2, 4, 8]
 
index ff5936e..dd56434 100644 (file)
@@ -58,13 +58,13 @@ properties:
 
   power-domains:
     description:
-       A phandle and PM domain specifier as defined by bindings of the power
-       controller specified by phandle. Some power domains might be powered
-       from another power domain (or have other hardware specific
-       dependencies). For representing such dependency a standard PM domain
-       consumer binding is used. When provided, all domains created
-       by the given provider should be subdomains of the domain specified
-       by this binding.
+      A phandle and PM domain specifier as defined by bindings of the power
+      controller specified by phandle. Some power domains might be powered
+      from another power domain (or have other hardware specific
+      dependencies). For representing such dependency a standard PM domain
+      consumer binding is used. When provided, all domains created
+      by the given provider should be subdomains of the domain specified
+      by this binding.
 
 required:
   - "#power-domain-cells"
index 30eabbb..6244b8e 100644 (file)
@@ -44,9 +44,9 @@ required:
 
 anyOf:
   - required:
-    - gpios
+      - gpios
   - required:
-    - charge-status-gpios
+      - charge-status-gpios
 
 additionalProperties: false
 
index d202220..c0d7700 100644 (file)
@@ -76,8 +76,7 @@ patternProperties:
 
   "^((s|l|lvs|5vs)[0-9]*)|(boost-bypass)|(bob)$":
     description: List of regulators and its properties
-    allOf:
-     - $ref: regulator.yaml#
+    $ref: regulator.yaml#
 
 additionalProperties: false
 
index 085cbd1..fb111e2 100644 (file)
@@ -29,7 +29,7 @@ properties:
           Short-circuit interrupt for lab.
 
     required:
-    - interrupts
+      - interrupts
 
   ibb:
     type: object
@@ -42,7 +42,7 @@ properties:
           Short-circuit interrupt for lab.
 
     required:
-    - interrupts
+      - interrupts
 
 required:
   - compatible
index 24b0c50..6070456 100644 (file)
@@ -118,16 +118,16 @@ else:
           - const: l1dram
 
 required:
- - compatible
- - reg
- - reg-names
- - ti,sci
- - ti,sci-dev-id
- - ti,sci-proc-ids
- - resets
- - firmware-name
- - mboxes
- - memory-region
 - compatible
 - reg
 - reg-names
 - ti,sci
 - ti,sci-dev-id
 - ti,sci-proc-ids
 - resets
 - firmware-name
 - mboxes
 - memory-region
 
 unevaluatedProperties: false
 
index b1a71c1..569cd3b 100644 (file)
@@ -24,9 +24,9 @@ properties:
   compatible:
     items:
       - enum:
-        - fsl,imx7d-src
-        - fsl,imx8mq-src
-        - fsl,imx8mp-src
+          - fsl,imx7d-src
+          - fsl,imx8mq-src
+          - fsl,imx8mp-src
       - const: syscon
 
   reg:
index 4206bf8..bc2c7e5 100644 (file)
@@ -16,16 +16,16 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4740-rtc
-        - ingenic,jz4760-rtc
+          - ingenic,jz4740-rtc
+          - ingenic,jz4760-rtc
       - items:
-        - const: ingenic,jz4725b-rtc
-        - const: ingenic,jz4740-rtc
+          - const: ingenic,jz4725b-rtc
+          - const: ingenic,jz4740-rtc
       - items:
-        - enum:
-          - ingenic,jz4770-rtc
-          - ingenic,jz4780-rtc
-        - const: ingenic,jz4760-rtc
+          - enum:
+              - ingenic,jz4770-rtc
+              - ingenic,jz4780-rtc
+          - const: ingenic,jz4760-rtc
 
   reg:
     maxItems: 1
index c023d65..dc83493 100644 (file)
@@ -16,18 +16,18 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4740-uart
-        - ingenic,jz4760-uart
-        - ingenic,jz4780-uart
-        - ingenic,x1000-uart
+          - ingenic,jz4740-uart
+          - ingenic,jz4760-uart
+          - ingenic,jz4780-uart
+          - ingenic,x1000-uart
       - items:
-        - enum:
-          - ingenic,jz4770-uart
-          - ingenic,jz4775-uart
-        - const: ingenic,jz4760-uart
+          - enum:
+              - ingenic,jz4770-uart
+              - ingenic,jz4775-uart
+          - const: ingenic,jz4760-uart
       - items:
-        - const: ingenic,jz4725b-uart
-        - const: ingenic,jz4740-uart
+          - const: ingenic,jz4725b-uart
+          - const: ingenic,jz4740-uart
 
   reg:
     maxItems: 1
index 3cd0b70..55fffae 100644 (file)
@@ -97,13 +97,13 @@ allOf:
         clock-names:
           oneOf:
             - items:
-              - const: t0_clk
-              - const: slow_clk
+                - const: t0_clk
+                - const: slow_clk
             - items:
-              - const: t0_clk
-              - const: t1_clk
-              - const: t2_clk
-              - const: slow_clk
+                - const: t0_clk
+                - const: t1_clk
+                - const: t2_clk
+                - const: slow_clk
 
 required:
   - compatible
index a2b29cc..bd04fdb 100644 (file)
@@ -7,8 +7,8 @@ $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 title: GENI Serial Engine QUP Wrapper Controller
 
 maintainers:
- - Mukesh Savaliya <msavaliy@codeaurora.org>
- - Akash Asthana <akashast@codeaurora.org>
 - Mukesh Savaliya <msavaliy@codeaurora.org>
 - Akash Asthana <akashast@codeaurora.org>
 
 description: |
  Generic Interface (GENI) based Qualcomm Universal Peripheral (QUP) wrapper
@@ -38,10 +38,10 @@ properties:
       - description: Slave AHB Clock
 
   "#address-cells":
-     const: 2
+    const: 2
 
   "#size-cells":
-     const: 2
+    const: 2
 
   ranges: true
 
@@ -79,15 +79,15 @@ patternProperties:
         maxItems: 1
 
       interconnects:
-         minItems: 2
-         maxItems: 3
+        minItems: 2
+        maxItems: 3
 
       interconnect-names:
-         minItems: 2
-         items:
-           - const: qup-core
-           - const: qup-config
-           - const: qup-memory
+        minItems: 2
+        items:
+          - const: qup-core
+          - const: qup-config
+          - const: qup-memory
 
     required:
       - reg
@@ -111,10 +111,10 @@ patternProperties:
         maxItems: 1
 
       "#address-cells":
-         const: 1
+        const: 1
 
       "#size-cells":
-         const: 0
+        const: 0
 
     required:
       - compatible
@@ -136,10 +136,10 @@ patternProperties:
         maxItems: 1
 
       "#address-cells":
-         const: 1
+        const: 1
 
       "#size-cells":
-         const: 0
+        const: 0
 
       clock-frequency:
         description: Desired I2C bus clock frequency in Hz.
index f9344ad..7a7f284 100644 (file)
@@ -19,12 +19,11 @@ properties:
   compatible:
     items:
       - enum:
-        - amlogic,aiu-gxbb
-        - amlogic,aiu-gxl
-        - amlogic,aiu-meson8
-        - amlogic,aiu-meson8b
-      - const:
-          amlogic,aiu
+          - amlogic,aiu-gxbb
+          - amlogic,aiu-gxl
+          - amlogic,aiu-meson8
+          - amlogic,aiu-meson8b
+      - const: amlogic,aiu
 
   clocks:
     items:
index 51a0c30..b4b3828 100644 (file)
@@ -19,13 +19,11 @@ properties:
   compatible:
     oneOf:
       - items:
-        - const:
-            amlogic,g12a-toacodec
+          - const: amlogic,g12a-toacodec
       - items:
-        - enum:
-          - amlogic,sm1-toacodec
-        - const:
-            amlogic,g12a-toacodec
+          - enum:
+              - amlogic,sm1-toacodec
+          - const: amlogic,g12a-toacodec
 
   reg:
     maxItems: 1
index 83f44f0..5bcb643 100644 (file)
@@ -11,7 +11,7 @@ maintainers:
 
 properties:
   compatible:
-      const: cirrus,cs42l51
+    const: cirrus,cs42l51
 
   reg:
     maxItems: 1
index 44f49be..cdc0fda 100644 (file)
@@ -16,13 +16,13 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4740-i2s
-        - ingenic,jz4760-i2s
-        - ingenic,jz4770-i2s
-        - ingenic,jz4780-i2s
+          - ingenic,jz4740-i2s
+          - ingenic,jz4760-i2s
+          - ingenic,jz4770-i2s
+          - ingenic,jz4780-i2s
       - items:
-        - const: ingenic,jz4725b-i2s
-        - const: ingenic,jz4740-i2s
+          - const: ingenic,jz4725b-i2s
+          - const: ingenic,jz4740-i2s
 
   '#sound-dai-cells':
     const: 0
index e5ac352..fea9a1b 100644 (file)
@@ -11,23 +11,21 @@ maintainers:
 
 properties:
   compatible:
-      const: maxim,max98390
+    const: maxim,max98390
 
   reg:
     maxItems: 1
     description: I2C address of the device.
 
   maxim,temperature_calib:
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/uint32
     description: The calculated temperature data was measured while doing the calibration.
+    $ref: /schemas/types.yaml#/definitions/uint32
     minimum: 0
     maximum: 65535
 
   maxim,r0_calib:
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/uint32
     description: This is r0 calibration data which was measured in factory mode.
+    $ref: /schemas/types.yaml#/definitions/uint32
     minimum: 1
     maximum: 8388607
 
index e620c77..2f2fcff 100644 (file)
@@ -48,8 +48,7 @@ properties:
 
   sound-name-prefix:
     pattern: "^DSPK[1-9]$"
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/string
+    $ref: /schemas/types.yaml#/definitions/string
     description:
       Used as prefix for sink/source names of the component. Must be a
       unique string among multiple instances of the same component.
index 1c14e83..8689d9f 100644 (file)
@@ -49,8 +49,7 @@ properties:
 
   sound-name-prefix:
     pattern: "^DMIC[1-9]$"
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/string
+    $ref: /schemas/types.yaml#/definitions/string
     description:
       used as prefix for sink/source names of the component. Must be a
       unique string among multiple instances of the same component.
index 7957970..9bbf181 100644 (file)
@@ -67,8 +67,7 @@ properties:
 
   sound-name-prefix:
     pattern: "^I2S[1-9]$"
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/string
+    $ref: /schemas/types.yaml#/definitions/string
     description:
       Used as prefix for sink/source names of the component. Must be a
       unique string among multiple instances of the same component.
index acb2b88..245895b 100644 (file)
@@ -19,16 +19,16 @@ properties:
       - const: rockchip,rk3066-i2s
       - items:
           - enum:
-            - rockchip,px30-i2s
-            - rockchip,rk3036-i2s
-            - rockchip,rk3188-i2s
-            - rockchip,rk3228-i2s
-            - rockchip,rk3288-i2s
-            - rockchip,rk3308-i2s
-            - rockchip,rk3328-i2s
-            - rockchip,rk3366-i2s
-            - rockchip,rk3368-i2s
-            - rockchip,rk3399-i2s
+              - rockchip,px30-i2s
+              - rockchip,rk3036-i2s
+              - rockchip,rk3188-i2s
+              - rockchip,rk3228-i2s
+              - rockchip,rk3288-i2s
+              - rockchip,rk3308-i2s
+              - rockchip,rk3328-i2s
+              - rockchip,rk3366-i2s
+              - rockchip,rk3368-i2s
+              - rockchip,rk3399-i2s
           - const: rockchip,rk3066-i2s
 
   reg:
@@ -55,8 +55,8 @@ properties:
     oneOf:
       - const: rx
       - items:
-        - const: tx
-        - const: rx
+          - const: tx
+          - const: rx
 
   power-domains:
     maxItems: 1
index c467152..7bad6f1 100644 (file)
@@ -25,8 +25,8 @@ properties:
       - const: rockchip,rk3399-spdif
       - items:
           - enum:
-            - rockchip,rk3188-spdif
-            - rockchip,rk3288-spdif
+              - rockchip,rk3188-spdif
+              - rockchip,rk3288-spdif
           - const: rockchip,rk3066-spdif
 
   reg:
index 8192450..33a90f8 100644 (file)
@@ -44,8 +44,8 @@ properties:
     $ref: /schemas/types.yaml#/definitions/uint32
     description: Sets TDM RX capture edge.
     enum:
-          - 0 # Rising edge
-          - 1 # Falling edge
+      - 0 # Rising edge
+      - 1 # Falling edge
 
   '#sound-dai-cells':
     const: 1
index 6f2be65..d52cfbe 100644 (file)
@@ -37,13 +37,11 @@ properties:
 
   ti,cpb-mcasp:
     description: phandle to McASP used on CPB
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   ti,cpb-codec:
     description: phandle to the pcm3168a codec used on the CPB
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   clocks:
     items:
index e0b8847..bb780f6 100644 (file)
@@ -50,28 +50,23 @@ properties:
 
   ti,cpb-mcasp:
     description: phandle to McASP used on CPB
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   ti,cpb-codec:
     description: phandle to the pcm3168a codec used on the CPB
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   ti,ivi-mcasp:
     description: phandle to McASP used on IVI
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   ti,ivi-codec-a:
     description: phandle to the pcm3168a-A codec on the expansion board
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   ti,ivi-codec-b:
     description: phandle to the pcm3168a-B codec on the expansion board
-    allOf:
-      - $ref: /schemas/types.yaml#/definitions/phandle
+    $ref: /schemas/types.yaml#/definitions/phandle
 
   clocks:
     items:
index e84d4a2..f578f17 100644 (file)
@@ -32,32 +32,32 @@ properties:
   reg:
     maxItems: 1
     description: |
-       I2C addresss of the device can be one of these 0x4c, 0x4d, 0x4e or 0x4f
+      I2C addresss of the device can be one of these 0x4c, 0x4d, 0x4e or 0x4f
 
   reset-gpios:
     description: |
-       GPIO used for hardware reset.
+      GPIO used for hardware reset.
 
   areg-supply:
-      description: |
-       Regulator with AVDD at 3.3V.  If not defined then the internal regulator
-       is enabled.
+    description: |
+      Regulator with AVDD at 3.3V.  If not defined then the internal regulator
+      is enabled.
 
   ti,mic-bias-source:
     description: |
-       Indicates the source for MIC Bias.
-       0 - Mic bias is set to VREF
-       1 - Mic bias is set to VREF Ã— 1.096
-       6 - Mic bias is set to AVDD
+      Indicates the source for MIC Bias.
+      0 - Mic bias is set to VREF
+      1 - Mic bias is set to VREF Ã— 1.096
+      6 - Mic bias is set to AVDD
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [0, 1, 6]
 
   ti,vref-source:
     description: |
-       Indicates the source for MIC Bias.
-       0 - Set VREF to 2.75V
-       1 - Set VREF to 2.5V
-       2 - Set VREF to 1.375V
+      Indicates the source for MIC Bias.
+      0 - Set VREF to 2.75V
+      1 - Set VREF to 2.5V
+      2 - Set VREF to 1.375V
     $ref: /schemas/types.yaml#/definitions/uint32
     enum: [0, 1, 2]
 
@@ -109,7 +109,7 @@ properties:
     default: [0, 0, 0, 0]
 
 patternProperties:
- '^ti,gpo-config-[1-4]$':
 '^ti,gpo-config-[1-4]$':
     $ref: /schemas/types.yaml#/definitions/uint32-array
     description: |
        Defines the configuration and output driver for the general purpose
index 243a6b1..7866a65 100644 (file)
@@ -22,10 +22,10 @@ properties:
       - const: allwinner,sun6i-a31-spi
       - const: allwinner,sun8i-h3-spi
       - items:
-        - enum:
-          - allwinner,sun8i-r40-spi
-          - allwinner,sun50i-h6-spi
-        - const: allwinner,sun8i-h3-spi
+          - enum:
+              - allwinner,sun8i-r40-spi
+              - allwinner,sun50i-h6-spi
+          - const: allwinner,sun8i-h3-spi
 
   reg:
     maxItems: 1
index 6e44c9c..1b50ced 100644 (file)
@@ -23,19 +23,19 @@ properties:
       - const: fsl,imx51-ecspi
       - const: fsl,imx53-ecspi
       - items:
-        - enum:
-          - fsl,imx50-ecspi
-          - fsl,imx6q-ecspi
-          - fsl,imx6sx-ecspi
-          - fsl,imx6sl-ecspi
-          - fsl,imx6sll-ecspi
-          - fsl,imx6ul-ecspi
-          - fsl,imx7d-ecspi
-          - fsl,imx8mq-ecspi
-          - fsl,imx8mm-ecspi
-          - fsl,imx8mn-ecspi
-          - fsl,imx8mp-ecspi
-        - const: fsl,imx51-ecspi
+          - enum:
+              - fsl,imx50-ecspi
+              - fsl,imx6q-ecspi
+              - fsl,imx6sx-ecspi
+              - fsl,imx6sl-ecspi
+              - fsl,imx6sll-ecspi
+              - fsl,imx6ul-ecspi
+              - fsl,imx7d-ecspi
+              - fsl,imx8mq-ecspi
+              - fsl,imx8mm-ecspi
+              - fsl,imx8mn-ecspi
+              - fsl,imx8mp-ecspi
+          - const: fsl,imx51-ecspi
 
   reg:
     maxItems: 1
index 22882e7..312d8fe 100644 (file)
@@ -39,6 +39,7 @@ properties:
       spi common code does not support use of CS signals discontinuously.
       i.MX8DXL-EVK board only uses CS1 without using CS0. Therefore, add
       this property to re-config the chipselect value in the LPSPI driver.
+    type: boolean
 
 required:
   - compatible
index 0ae692d..3d3fed6 100644 (file)
@@ -43,47 +43,47 @@ properties:
     maxItems: 1
 
 required:
-   - compatible
-   - reg
-   - spi-max-frequency
-   - mux-controls
+  - compatible
+  - reg
+  - spi-max-frequency
+  - mux-controls
 
 examples:
-   - |
-     #include <dt-bindings/gpio/gpio.h>
-     mux: mux-controller {
-       compatible = "gpio-mux";
-       #mux-control-cells = <0>;
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    mux: mux-controller {
+        compatible = "gpio-mux";
+        #mux-control-cells = <0>;
 
-       mux-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
-     };
+        mux-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
+    };
 
-     spi {
-       #address-cells = <1>;
-       #size-cells = <0>;
-       spi@0 {
-         compatible = "spi-mux";
-         reg = <0>;
-         #address-cells = <1>;
-         #size-cells = <0>;
-         spi-max-frequency = <100000000>;
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        spi@0 {
+            compatible = "spi-mux";
+            reg = <0>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+            spi-max-frequency = <100000000>;
 
-         mux-controls = <&mux>;
+            mux-controls = <&mux>;
 
-         spi-flash@0 {
-           compatible = "jedec,spi-nor";
-           reg = <0>;
-           #address-cells = <1>;
-           #size-cells = <0>;
-           spi-max-frequency = <40000000>;
-         };
+            spi-flash@0 {
+                compatible = "jedec,spi-nor";
+                reg = <0>;
+                #address-cells = <1>;
+                #size-cells = <0>;
+                spi-max-frequency = <40000000>;
+            };
 
-         spi-device@1 {
-           compatible = "lineartechnology,ltc2488";
-           reg = <1>;
-           #address-cells = <1>;
-           #size-cells = <0>;
-           spi-max-frequency = <10000000>;
-         };
-       };
-     };
+            spi-device@1 {
+                compatible = "lineartechnology,ltc2488";
+                reg = <1>;
+                #address-cells = <1>;
+                #size-cells = <0>;
+                spi-max-frequency = <10000000>;
+            };
+        };
+    };
index 81ad4b7..74dc618 100644 (file)
@@ -26,13 +26,13 @@ properties:
       - const: rockchip,rv1108-spi
       - items:
           - enum:
-            - rockchip,px30-spi
-            - rockchip,rk3188-spi
-            - rockchip,rk3288-spi
-            - rockchip,rk3308-spi
-            - rockchip,rk3328-spi
-            - rockchip,rk3368-spi
-            - rockchip,rk3399-spi
+              - rockchip,px30-spi
+              - rockchip,rk3188-spi
+              - rockchip,rk3288-spi
+              - rockchip,rk3308-spi
+              - rockchip,rk3328-spi
+              - rockchip,rk3368-spi
+              - rockchip,rk3399-spi
           - const: rockchip,rk3066-spi
 
   reg:
index 5145883..ad4beaf 100644 (file)
@@ -44,9 +44,9 @@ select: true
 properties:
   "#cooling-cells":
     description:
-        Must be 2, in order to specify minimum and maximum cooling state used in
-        the cooling-maps reference. The first cell is the minimum cooling state
-        and the second cell is the maximum cooling state requested.
+      Must be 2, in order to specify minimum and maximum cooling state used in
+      the cooling-maps reference. The first cell is the minimum cooling state
+      and the second cell is the maximum cooling state requested.
     const: 2
 
 examples:
index 7a922f5..a832d42 100644 (file)
@@ -18,29 +18,28 @@ description: |
   This binding describes the thermal idle node.
 
 properties:
-   $nodename:
-     const: thermal-idle
-     description: |
-        A thermal-idle node describes the idle cooling device properties to
-        cool down efficiently the attached thermal zone.
-
-   '#cooling-cells':
-      const: 2
-      description: |
-         Must be 2, in order to specify minimum and maximum cooling state used in
-         the cooling-maps reference. The first cell is the minimum cooling state
-         and the second cell is the maximum cooling state requested.
-
-   duration-us:
-      description: |
-         The idle duration in microsecond the device should cool down.
-
-   exit-latency-us:
-      description: |
-         The exit latency constraint in microsecond for the injected
-         idle state for the device. It is the latency constraint to
-         apply when selecting an idle state from among all the present
-         ones.
+  $nodename:
+    const: thermal-idle
+    description: |
+      A thermal-idle node describes the idle cooling device properties to
+      cool down efficiently the attached thermal zone.
+
+  '#cooling-cells':
+    const: 2
+    description: |
+      Must be 2, in order to specify minimum and maximum cooling state used in
+      the cooling-maps reference. The first cell is the minimum cooling state
+      and the second cell is the maximum cooling state requested.
+
+  duration-us:
+    description: |
+      The idle duration in microsecond the device should cool down.
+
+  exit-latency-us:
+    description: |
+      The exit latency constraint in microsecond for the injected idle state 
+      for the device. It is the latency constraint to apply when selecting an 
+      idle state from among all the present ones.
 
 required:
   - '#cooling-cells'
index 883f7f4..a4f51f4 100644 (file)
@@ -20,17 +20,17 @@ properties:
       - const: fsl,imx31-gpt
       - items:
           - enum:
-            - fsl,imx25-gpt
-            - fsl,imx50-gpt
-            - fsl,imx51-gpt
-            - fsl,imx53-gpt
-            - fsl,imx6q-gpt
+              - fsl,imx25-gpt
+              - fsl,imx50-gpt
+              - fsl,imx51-gpt
+              - fsl,imx53-gpt
+              - fsl,imx6q-gpt
           - const: fsl,imx31-gpt
       - const: fsl,imx6dl-gpt
       - items:
           - enum:
-            - fsl,imx6sl-gpt
-            - fsl,imx6sx-gpt
+              - fsl,imx6sl-gpt
+              - fsl,imx6sx-gpt
           - const: fsl,imx6dl-gpt
 
   reg:
index 371fb02..024bcad 100644 (file)
@@ -49,16 +49,16 @@ properties:
   compatible:
     oneOf:
       - items:
-        - enum:
-          - ingenic,jz4740-tcu
-          - ingenic,jz4725b-tcu
-          - ingenic,jz4770-tcu
-          - ingenic,x1000-tcu
-        - const: simple-mfd
+          - enum:
+              - ingenic,jz4740-tcu
+              - ingenic,jz4725b-tcu
+              - ingenic,jz4770-tcu
+              - ingenic,x1000-tcu
+          - const: simple-mfd
       - items:
-        - const: ingenic,jz4780-tcu
-        - const: ingenic,jz4770-tcu
-        - const: simple-mfd
+          - const: ingenic,jz4780-tcu
+          - const: ingenic,jz4770-tcu
+          - const: simple-mfd
 
   reg:
     maxItems: 1
@@ -113,13 +113,13 @@ patternProperties:
       compatible:
         oneOf:
           - enum:
-            - ingenic,jz4740-watchdog
-            - ingenic,jz4780-watchdog
+              - ingenic,jz4740-watchdog
+              - ingenic,jz4780-watchdog
           - items:
-            - enum:
-              - ingenic,jz4770-watchdog
-              - ingenic,jz4725b-watchdog
-            - const: ingenic,jz4740-watchdog
+              - enum:
+                  - ingenic,jz4770-watchdog
+                  - ingenic,jz4725b-watchdog
+              - const: ingenic,jz4740-watchdog
 
       reg:
         maxItems: 1
@@ -143,13 +143,13 @@ patternProperties:
       compatible:
         oneOf:
           - enum:
-            - ingenic,jz4740-pwm
-            - ingenic,jz4725b-pwm
+              - ingenic,jz4740-pwm
+              - ingenic,jz4725b-pwm
           - items:
-            - enum:
-              - ingenic,jz4770-pwm
-              - ingenic,jz4780-pwm
-            - const: ingenic,jz4740-pwm
+              - enum:
+                  - ingenic,jz4770-pwm
+                  - ingenic,jz4780-pwm
+              - const: ingenic,jz4740-pwm
 
       reg:
         maxItems: 1
@@ -182,11 +182,11 @@ patternProperties:
       compatible:
         oneOf:
           - enum:
-            - ingenic,jz4725b-ost
-            - ingenic,jz4770-ost
+              - ingenic,jz4725b-ost
+              - ingenic,jz4770-ost
           - items:
-            - const: ingenic,jz4780-ost
-            - const: ingenic,jz4770-ost
+              - const: ingenic,jz4780-ost
+              - const: ingenic,jz4770-ost
 
       reg:
         maxItems: 1
index 5d300ef..7b39e32 100644 (file)
@@ -27,8 +27,8 @@ properties:
   clocks:
     minItems: 1
     items:
-       - description: Timer ticks reference clock source
-       - description: APB interface clock source
+      - description: Timer ticks reference clock source
+      - description: APB interface clock source
 
   clock-names:
     minItems: 1
index b7e94fe..4ace803 100644 (file)
@@ -298,7 +298,7 @@ properties:
           - national,lm80
             # Temperature sensor with integrated fan control
           - national,lm85
-            # Â±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator with Two-Wire Interface
+            # I2C Â±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator
           - national,lm92
             # i2c trusted platform module (TPM)
           - nuvoton,npct501
index 4ff632d..ffa157a 100644 (file)
@@ -19,24 +19,24 @@ properties:
           - const: snps,dwc2
       - items:
           - enum:
-            - rockchip,px30-usb
-            - rockchip,rk3036-usb
-            - rockchip,rk3188-usb
-            - rockchip,rk3228-usb
-            - rockchip,rk3288-usb
-            - rockchip,rk3328-usb
-            - rockchip,rk3368-usb
-            - rockchip,rv1108-usb
+              - rockchip,px30-usb
+              - rockchip,rk3036-usb
+              - rockchip,rk3188-usb
+              - rockchip,rk3228-usb
+              - rockchip,rk3288-usb
+              - rockchip,rk3328-usb
+              - rockchip,rk3368-usb
+              - rockchip,rv1108-usb
           - const: rockchip,rk3066-usb
           - const: snps,dwc2
       - const: lantiq,arx100-usb
       - const: lantiq,xrx200-usb
       - items:
           - enum:
-            - amlogic,meson8-usb
-            - amlogic,meson8b-usb
-            - amlogic,meson-gxbb-usb
-            - amlogic,meson-g12a-usb
+              - amlogic,meson8-usb
+              - amlogic,meson8b-usb
+              - amlogic,meson-gxbb-usb
+              - amlogic,meson-g12a-usb
           - const: snps,dwc2
       - const: amcc,dwc-otg
       - const: snps,dwc2
@@ -116,12 +116,13 @@ properties:
 
   snps,need-phy-for-wake:
     $ref: /schemas/types.yaml#/definitions/flag
-    description: If present indicates that the phy needs to be left on for remote wakeup during suspend.
+    description: If present indicates that the phy needs to be left on for 
+      remote wakeup during suspend.
 
   snps,reset-phy-on-wake:
     $ref: /schemas/types.yaml#/definitions/flag
-    description: If present indicates that we need to reset the PHY when we detect a wakeup.
-                 This is due to a hardware errata.
+    description: If present indicates that we need to reset the PHY when we 
+      detect a wakeup. This is due to a hardware errata.
 
 required:
   - compatible
index 69f3f26..247ef00 100644 (file)
@@ -80,7 +80,7 @@ properties:
   companion:
     $ref: /schemas/types.yaml#/definitions/phandle
     description:
-     Phandle of a companion.
+      Phandle of a companion.
 
   phys:
     description: PHY specifier for the USB PHY
index c334aea..678396e 100644 (file)
@@ -16,11 +16,11 @@ properties:
   compatible:
     oneOf:
       - enum:
-        - ingenic,jz4770-musb
-        - ingenic,jz4740-musb
+          - ingenic,jz4770-musb
+          - ingenic,jz4740-musb
       - items:
-        - const: ingenic,jz4725b-musb
-        - const: ingenic,jz4740-musb
+          - const: ingenic,jz4725b-musb
+          - const: ingenic,jz4740-musb
 
   reg:
     maxItems: 1
index 0073763..196589c 100644 (file)
@@ -57,11 +57,11 @@ properties:
     minItems: 4
     maxItems: 5
     items:
-     - const: dev
-     - const: ss
-     - const: ss_src
-     - const: fs_src
-     - const: hs_src
+      - const: dev
+      - const: ss
+      - const: ss_src
+      - const: fs_src
+      - const: hs_src
 
   power-domains:
     items:
index 9075025..484fc10 100644 (file)
@@ -19,9 +19,9 @@ properties:
 
   power-domains:
     description:
-       PM domain provider node and an args specifier containing
-       the USB device id value. See,
-       Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
+      PM domain provider node and an args specifier containing
+      the USB device id value. See,
+      Documentation/devicetree/bindings/soc/ti/sci-pm-domain.txt
 
   clocks:
     description: Clock phandles to usb2_refclk and lpm_clk
index 804b9b4..c1b19fc 100644 (file)
@@ -13,8 +13,8 @@ properties:
   compatible:
     items:
       - enum:
-        - ti,keystone-dwc3
-        - ti,am654-dwc3
+          - ti,keystone-dwc3
+          - ti,am654-dwc3
 
   reg:
     maxItems: 1
index f3d8478..2baee2c 100644 (file)
@@ -993,7 +993,8 @@ patternProperties:
   "^sst,.*":
     description: Silicon Storage Technology, Inc.
   "^sstar,.*":
-    description: Xiamen Xingchen(SigmaStar) Technology Co., Ltd. (formerly part of MStar Semiconductor, Inc.)
+    description: Xiamen Xingchen(SigmaStar) Technology Co., Ltd. 
+      (formerly part of MStar Semiconductor, Inc.)
   "^st,.*":
     description: STMicroelectronics
   "^starry,.*":
index 902b93b..5ef2cfe 100644 (file)
@@ -100,7 +100,6 @@ available subsections can be seen below.
    rfkill
    serial/index
    sm501
-   smsc_ece1099
    switchtec
    sync_file
    vfio-mediated-device
diff --git a/Documentation/driver-api/smsc_ece1099.rst b/Documentation/driver-api/smsc_ece1099.rst
deleted file mode 100644 (file)
index 0792774..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-=================================================
-Msc Keyboard Scan Expansion/GPIO Expansion device
-=================================================
-
-What is smsc-ece1099?
-----------------------
-
-The ECE1099 is a 40-Pin 3.3V Keyboard Scan Expansion
-or GPIO Expansion device. The device supports a keyboard
-scan matrix of 23x8. The device is connected to a Master
-via the SMSC BC-Link interface or via the SMBus.
-Keypad scan Input(KSI) and Keypad Scan Output(KSO) signals
-are multiplexed with GPIOs.
-
-Interrupt generation
---------------------
-
-Interrupts can be generated by an edge detection on a GPIO
-pin or an edge detection on one of the bus interface pins.
-Interrupts can also be detected on the keyboard scan interface.
-The bus interrupt pin (BC_INT# or SMBUS_INT#) is asserted if
-any bit in one of the Interrupt Status registers is 1 and
-the corresponding Interrupt Mask bit is also 1.
-
-In order for software to determine which device is the source
-of an interrupt, it should first read the Group Interrupt Status Register
-to determine which Status register group is a source for the interrupt.
-Software should read both the Status register and the associated Mask register,
-then AND the two values together. Bits that are 1 in the result of the AND
-are active interrupts. Software clears an interrupt by writing a 1 to the
-corresponding bit in the Status register.
-
-Communication Protocol
-----------------------
-
-- SMbus slave Interface
-       The host processor communicates with the ECE1099 device
-       through a series of read/write registers via the SMBus
-       interface. SMBus is a serial communication protocol between
-       a computer host and its peripheral devices. The SMBus data
-       rate is 10KHz minimum to 400 KHz maximum
-
-- Slave Bus Interface
-       The ECE1099 device SMBus implementation is a subset of the
-       SMBus interface to the host. The device is a slave-only SMBus device.
-       The implementation in the device is a subset of SMBus since it
-       only supports four protocols.
-
-       The Write Byte, Read Byte, Send Byte, and Receive Byte protocols are the
-       only valid SMBus protocols for the device.
-
-- BC-LinkTM Interface
-       The BC-Link is a proprietary bus that allows communication
-       between a Master device and a Companion device. The Master
-       device uses this serial bus to read and write registers
-       located on the Companion device. The bus comprises three signals,
-       BC_CLK, BC_DAT and BC_INT#. The Master device always provides the
-       clock, BC_CLK, and the Companion device is the source for an
-       independent asynchronous interrupt signal, BC_INT#. The ECE1099
-       supports BC-Link speeds up to 24MHz.
index 24168b0..adc3146 100644 (file)
@@ -2860,17 +2860,6 @@ version of the linux kernel, found on http://kernel.org
 The latest version of this document can be found in the latest kernel
 source (named Documentation/networking/bonding.rst).
 
-Discussions regarding the usage of the bonding driver take place on the
-bonding-devel mailing list, hosted at sourceforge.net. If you have questions or
-problems, post them to the list.  The list address is:
-
-bonding-devel@lists.sourceforge.net
-
-The administrative interface (to subscribe or unsubscribe) can
-be found at:
-
-https://lists.sourceforge.net/lists/listinfo/bonding-devel
-
 Discussions regarding the development of the bonding driver take place
 on the main Linux network mailing list, hosted at vger.kernel.org. The list
 address is:
@@ -2881,10 +2870,3 @@ The administrative interface (to subscribe or unsubscribe) can
 be found at:
 
 http://vger.kernel.org/vger-lists.html#netdev
-
-Donald Becker's Ethernet Drivers and diag programs may be found at :
-
- - http://web.archive.org/web/%2E/http://www.scyld.com/network/
-
-You will also find a lot of information regarding Ethernet, NWay, MII,
-etc. at www.scyld.com.
index 2843eff..deaafb6 100644 (file)
@@ -9678,6 +9678,15 @@ F:       include/linux/kdb.h
 F:     include/linux/kgdb.h
 F:     kernel/debug/
 
+KHADAS MCU MFD DRIVER
+M:     Neil Armstrong <narmstrong@baylibre.com>
+L:     linux-amlogic@lists.infradead.org
+S:     Maintained
+F:     Documentation/devicetree/bindings/mfd/khadas,mcu.yaml
+F:     drivers/mfd/khadas-mcu.c
+F:     include/linux/mfd/khadas-mcu.h
+F:     drivers/thermal/khadas_mcu_fan.c
+
 KMEMLEAK
 M:     Catalin Marinas <catalin.marinas@arm.com>
 S:     Maintained
@@ -13557,6 +13566,7 @@ F:      arch/*/kernel/perf_event*.c
 F:     include/linux/perf_event.h
 F:     include/uapi/linux/perf_event.h
 F:     kernel/events/*
+F:     tools/lib/perf/
 F:     tools/perf/
 
 PERFORMANCE EVENTS SUBSYSTEM ARM64 PMU EVENTS
@@ -14887,6 +14897,13 @@ L:     linux-serial@vger.kernel.org
 S:     Odd Fixes
 F:     drivers/tty/serial/rp2.*
 
+ROHM BD99954 CHARGER IC
+R:     Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+L:     linux-power@fi.rohmeurope.com
+S:     Supported
+F:     drivers/power/supply/bd99954-charger.c
+F:     drivers/power/supply/bd99954-charger.h
+
 ROHM BH1750 AMBIENT LIGHT SENSOR DRIVER
 M:     Tomasz Duszynski <tduszyns@gmail.com>
 S:     Maintained
@@ -14904,6 +14921,31 @@ F:     drivers/mfd/bd9571mwv.c
 F:     drivers/regulator/bd9571mwv-regulator.c
 F:     include/linux/mfd/bd9571mwv.h
 
+ROHM POWER MANAGEMENT IC DEVICE DRIVERS
+R:     Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+L:     linux-power@fi.rohmeurope.com
+S:     Supported
+F:     Documentation/devicetree/bindings/mfd/rohm,bd70528-pmic.txt
+F:     Documentation/devicetree/bindings/regulator/rohm,bd70528-regulator.txt
+F:     drivers/clk/clk-bd718x7.c
+F:     drivers/gpio/gpio-bd70528.c
+F:     drivers/gpio/gpio-bd71828.c
+F:     drivers/mfd/rohm-bd70528.c
+F:     drivers/mfd/rohm-bd71828.c
+F:     drivers/mfd/rohm-bd718x7.c
+F:     drivers/power/supply/bd70528-charger.c
+F:     drivers/regulator/bd70528-regulator.c
+F:     drivers/regulator/bd71828-regulator.c
+F:     drivers/regulator/bd718x7-regulator.c
+F:     drivers/regulator/rohm-regulator.c
+F:     drivers/rtc/rtc-bd70528.c
+F:     drivers/watchdog/bd70528_wdt.c
+F:     include/linux/mfd/rohm-bd70528.h
+F:     include/linux/mfd/rohm-bd71828.h
+F:     include/linux/mfd/rohm-bd718x7.h
+F:     include/linux/mfd/rohm-generic.h
+F:     include/linux/mfd/rohm-shared.h
+
 ROSE NETWORK LAYER
 M:     Ralf Baechle <ralf@linux-mips.org>
 L:     linux-hams@vger.kernel.org
index 254e80a..9cac6fd 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 VERSION = 5
-PATCHLEVEL = 8
+PATCHLEVEL = 9
 SUBLEVEL = 0
-EXTRAVERSION =
+EXTRAVERSION = -rc1
 NAME = Kleptomaniac Octopus
 
 # *DOCUMENTATION*
index 3329fa1..af14a56 100644 (file)
@@ -972,6 +972,9 @@ config HAVE_SPARSE_SYSCALL_NR
          entries at 4000, 5000 and 6000 locations. This option turns on syscall
          related optimizations for a given architecture.
 
+config ARCH_HAS_VDSO_DATA
+       bool
+
 source "kernel/gcov/Kconfig"
 
 source "scripts/gcc-plugins/Kconfig"
index 0a07055..2d9726f 100644 (file)
@@ -384,7 +384,7 @@ struct el_apecs_procdata
                }                                               \
        } while (0)
 
-__EXTERN_INLINE unsigned int apecs_ioread8(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int apecs_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -420,7 +420,7 @@ __EXTERN_INLINE void apecs_iowrite8(u8 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int apecs_ioread16(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int apecs_ioread16(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -456,7 +456,7 @@ __EXTERN_INLINE void apecs_iowrite16(u16 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int apecs_ioread32(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int apecs_ioread32(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        if (addr < APECS_DENSE_MEM)
index c706a7f..cb22991 100644 (file)
@@ -342,7 +342,7 @@ struct el_CIA_sysdata_mcheck {
 #define vuip   volatile unsigned int __force *
 #define vulp   volatile unsigned long __force *
 
-__EXTERN_INLINE unsigned int cia_ioread8(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int cia_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -374,7 +374,7 @@ __EXTERN_INLINE void cia_iowrite8(u8 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int cia_ioread16(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int cia_ioread16(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -404,7 +404,7 @@ __EXTERN_INLINE void cia_iowrite16(u16 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int cia_ioread32(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int cia_ioread32(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        if (addr < CIA_DENSE_MEM)
index 84d5e5b..ec86314 100644 (file)
@@ -230,7 +230,7 @@ union el_lca {
        } while (0)
 
 
-__EXTERN_INLINE unsigned int lca_ioread8(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int lca_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -266,7 +266,7 @@ __EXTERN_INLINE void lca_iowrite8(u8 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int lca_ioread16(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int lca_ioread16(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        unsigned long result, base_and_type;
@@ -302,7 +302,7 @@ __EXTERN_INLINE void lca_iowrite16(u16 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + base_and_type) = w;
 }
 
-__EXTERN_INLINE unsigned int lca_ioread32(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int lca_ioread32(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        if (addr < LCA_DENSE_MEM)
index cc6fd92..b266e02 100644 (file)
@@ -332,10 +332,10 @@ struct io7 {
 #define vucp   volatile unsigned char __force *
 #define vusp   volatile unsigned short __force *
 
-extern unsigned int marvel_ioread8(void __iomem *);
+extern unsigned int marvel_ioread8(const void __iomem *);
 extern void marvel_iowrite8(u8 b, void __iomem *);
 
-__EXTERN_INLINE unsigned int marvel_ioread16(void __iomem *addr)
+__EXTERN_INLINE unsigned int marvel_ioread16(const void __iomem *addr)
 {
        return __kernel_ldwu(*(vusp)addr);
 }
index b30dc12..cb24d1b 100644 (file)
@@ -267,7 +267,7 @@ extern inline int __mcpcia_is_mmio(unsigned long addr)
        return (addr & 0x80000000UL) == 0;
 }
 
-__EXTERN_INLINE unsigned int mcpcia_ioread8(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int mcpcia_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
        unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
@@ -291,7 +291,7 @@ __EXTERN_INLINE void mcpcia_iowrite8(u8 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + hose + 0x00) = w;
 }
 
-__EXTERN_INLINE unsigned int mcpcia_ioread16(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int mcpcia_ioread16(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long)xaddr & MCPCIA_MEM_MASK;
        unsigned long hose = (unsigned long)xaddr & ~MCPCIA_MEM_MASK;
@@ -315,7 +315,7 @@ __EXTERN_INLINE void mcpcia_iowrite16(u16 b, void __iomem *xaddr)
        *(vuip) ((addr << 5) + hose + 0x08) = w;
 }
 
-__EXTERN_INLINE unsigned int mcpcia_ioread32(void __iomem *xaddr)
+__EXTERN_INLINE unsigned int mcpcia_ioread32(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long)xaddr;
 
index e0b33d0..12bb7ad 100644 (file)
@@ -572,7 +572,7 @@ __EXTERN_INLINE int t2_is_mmio(const volatile void __iomem *addr)
    it doesn't make sense to merge the pio and mmio routines.  */
 
 #define IOPORT(OS, NS)                                                 \
-__EXTERN_INLINE unsigned int t2_ioread##NS(void __iomem *xaddr)                \
+__EXTERN_INLINE unsigned int t2_ioread##NS(const void __iomem *xaddr)          \
 {                                                                      \
        if (t2_is_mmio(xaddr))                                          \
                return t2_read##OS(xaddr);                              \
index 640e1a2..1f6a909 100644 (file)
@@ -150,9 +150,9 @@ static inline void generic_##NAME(TYPE b, QUAL void __iomem *addr)  \
        alpha_mv.mv_##NAME(b, addr);                                    \
 }
 
-REMAP1(unsigned int, ioread8, /**/)
-REMAP1(unsigned int, ioread16, /**/)
-REMAP1(unsigned int, ioread32, /**/)
+REMAP1(unsigned int, ioread8, const)
+REMAP1(unsigned int, ioread16, const)
+REMAP1(unsigned int, ioread32, const)
 REMAP1(u8, readb, const volatile)
 REMAP1(u16, readw, const volatile)
 REMAP1(u32, readl, const volatile)
@@ -307,7 +307,7 @@ static inline int __is_mmio(const volatile void __iomem *addr)
  */
 
 #if IO_CONCAT(__IO_PREFIX,trivial_io_bw)
-extern inline unsigned int ioread8(void __iomem *addr)
+extern inline unsigned int ioread8(const void __iomem *addr)
 {
        unsigned int ret;
        mb();
@@ -316,7 +316,7 @@ extern inline unsigned int ioread8(void __iomem *addr)
        return ret;
 }
 
-extern inline unsigned int ioread16(void __iomem *addr)
+extern inline unsigned int ioread16(const void __iomem *addr)
 {
        unsigned int ret;
        mb();
@@ -359,7 +359,7 @@ extern inline void outw(u16 b, unsigned long port)
 #endif
 
 #if IO_CONCAT(__IO_PREFIX,trivial_io_lq)
-extern inline unsigned int ioread32(void __iomem *addr)
+extern inline unsigned int ioread32(const void __iomem *addr)
 {
        unsigned int ret;
        mb();
index ba3d8f0..a1a29cb 100644 (file)
@@ -7,15 +7,15 @@
 
 #if IO_CONCAT(__IO_PREFIX,trivial_io_bw)
 __EXTERN_INLINE unsigned int
-IO_CONCAT(__IO_PREFIX,ioread8)(void __iomem *a)
+IO_CONCAT(__IO_PREFIX,ioread8)(const void __iomem *a)
 {
-       return __kernel_ldbu(*(volatile u8 __force *)a);
+       return __kernel_ldbu(*(const volatile u8 __force *)a);
 }
 
 __EXTERN_INLINE unsigned int
-IO_CONCAT(__IO_PREFIX,ioread16)(void __iomem *a)
+IO_CONCAT(__IO_PREFIX,ioread16)(const void __iomem *a)
 {
-       return __kernel_ldwu(*(volatile u16 __force *)a);
+       return __kernel_ldwu(*(const volatile u16 __force *)a);
 }
 
 __EXTERN_INLINE void
@@ -33,9 +33,9 @@ IO_CONCAT(__IO_PREFIX,iowrite16)(u16 b, void __iomem *a)
 
 #if IO_CONCAT(__IO_PREFIX,trivial_io_lq)
 __EXTERN_INLINE unsigned int
-IO_CONCAT(__IO_PREFIX,ioread32)(void __iomem *a)
+IO_CONCAT(__IO_PREFIX,ioread32)(const void __iomem *a)
 {
-       return *(volatile u32 __force *)a;
+       return *(const volatile u32 __force *)a;
 }
 
 __EXTERN_INLINE void
@@ -73,14 +73,14 @@ IO_CONCAT(__IO_PREFIX,writew)(u16 b, volatile void __iomem *a)
 __EXTERN_INLINE u8
 IO_CONCAT(__IO_PREFIX,readb)(const volatile void __iomem *a)
 {
-       void __iomem *addr = (void __iomem *)a;
+       const void __iomem *addr = (const void __iomem *)a;
        return IO_CONCAT(__IO_PREFIX,ioread8)(addr);
 }
 
 __EXTERN_INLINE u16
 IO_CONCAT(__IO_PREFIX,readw)(const volatile void __iomem *a)
 {
-       void __iomem *addr = (void __iomem *)a;
+       const void __iomem *addr = (const void __iomem *)a;
        return IO_CONCAT(__IO_PREFIX,ioread16)(addr);
 }
 
index 436dc90..9168951 100644 (file)
@@ -305,7 +305,7 @@ __EXTERN_INLINE int jensen_is_mmio(const volatile void __iomem *addr)
    that it doesn't make sense to merge them.  */
 
 #define IOPORT(OS, NS)                                                 \
-__EXTERN_INLINE unsigned int jensen_ioread##NS(void __iomem *xaddr)    \
+__EXTERN_INLINE unsigned int jensen_ioread##NS(const void __iomem *xaddr)      \
 {                                                                      \
        if (jensen_is_mmio(xaddr))                                      \
                return jensen_read##OS(xaddr - 0x100000000ul);          \
index a6b73c6..a4e96e2 100644 (file)
@@ -46,9 +46,9 @@ struct alpha_machine_vector
        void (*mv_pci_tbi)(struct pci_controller *hose,
                           dma_addr_t start, dma_addr_t end);
 
-       unsigned int (*mv_ioread8)(void __iomem *);
-       unsigned int (*mv_ioread16)(void __iomem *);
-       unsigned int (*mv_ioread32)(void __iomem *);
+       unsigned int (*mv_ioread8)(const void __iomem *);
+       unsigned int (*mv_ioread16)(const void __iomem *);
+       unsigned int (*mv_ioread32)(const void __iomem *);
 
        void (*mv_iowrite8)(u8, void __iomem *);
        void (*mv_iowrite16)(u16, void __iomem *);
index 4c80d99..4485b77 100644 (file)
@@ -806,7 +806,7 @@ void __iomem *marvel_ioportmap (unsigned long addr)
 }
 
 unsigned int
-marvel_ioread8(void __iomem *xaddr)
+marvel_ioread8(const void __iomem *xaddr)
 {
        unsigned long addr = (unsigned long) xaddr;
        if (__marvel_is_port_kbd(addr))
index 938de13..838586a 100644 (file)
@@ -14,7 +14,7 @@
    "generic", which bumps through the machine vector.  */
 
 unsigned int
-ioread8(void __iomem *addr)
+ioread8(const void __iomem *addr)
 {
        unsigned int ret;
        mb();
@@ -23,7 +23,7 @@ ioread8(void __iomem *addr)
        return ret;
 }
 
-unsigned int ioread16(void __iomem *addr)
+unsigned int ioread16(const void __iomem *addr)
 {
        unsigned int ret;
        mb();
@@ -32,7 +32,7 @@ unsigned int ioread16(void __iomem *addr)
        return ret;
 }
 
-unsigned int ioread32(void __iomem *addr)
+unsigned int ioread32(const void __iomem *addr)
 {
        unsigned int ret;
        mb();
@@ -257,7 +257,7 @@ EXPORT_SYMBOL(readq_relaxed);
 /*
  * Read COUNT 8-bit bytes from port PORT into memory starting at SRC.
  */
-void ioread8_rep(void __iomem *port, void *dst, unsigned long count)
+void ioread8_rep(const void __iomem *port, void *dst, unsigned long count)
 {
        while ((unsigned long)dst & 0x3) {
                if (!count)
@@ -300,7 +300,7 @@ EXPORT_SYMBOL(insb);
  * the interfaces seems to be slow: just using the inlined version
  * of the inw() breaks things.
  */
-void ioread16_rep(void __iomem *port, void *dst, unsigned long count)
+void ioread16_rep(const void __iomem *port, void *dst, unsigned long count)
 {
        if (unlikely((unsigned long)dst & 0x3)) {
                if (!count)
@@ -340,7 +340,7 @@ EXPORT_SYMBOL(insw);
  * but the interfaces seems to be slow: just using the inlined version
  * of the inl() breaks things.
  */
-void ioread32_rep(void __iomem *port, void *dst, unsigned long count)
+void ioread32_rep(const void __iomem *port, void *dst, unsigned long count)
 {
        if (unlikely((unsigned long)dst & 0x3)) {
                while (count--) {
index a28fb21..ec8bed9 100644 (file)
 316    common  mlockall                        sys_mlockall
 317    common  munlockall                      sys_munlockall
 318    common  sysinfo                         sys_sysinfo
-319    common  _sysctl                         sys_sysctl
+319    common  _sysctl                         sys_ni_syscall
 # 320 was sys_idle
 321    common  oldumount                       sys_oldumount
 322    common  swapon                          sys_swapon
index f56ac39..4e49d6c 100644 (file)
@@ -3,7 +3,6 @@ CONFIG_LOCALVERSION="gum"
 CONFIG_SYSVIPC=y
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
 # CONFIG_VM_EVENT_COUNTERS is not set
index 1b207cf..2134cbd 100644 (file)
@@ -113,7 +113,8 @@ static inline bool arm_vdso_hres_capable(void)
 }
 #define __arch_vdso_hres_capable arm_vdso_hres_capable
 
-static __always_inline u64 __arch_get_hw_counter(int clock_mode)
+static __always_inline u64 __arch_get_hw_counter(int clock_mode,
+                                                const struct vdso_data *vd)
 {
 #ifdef CONFIG_ARM_ARCH_TIMER
        u64 cycle_now;
index 7e8ee4a..171077c 100644 (file)
 146    common  writev                  sys_writev
 147    common  getsid                  sys_getsid
 148    common  fdatasync               sys_fdatasync
-149    common  _sysctl                 sys_sysctl
+149    common  _sysctl                 sys_ni_syscall
 150    common  mlock                   sys_mlock
 151    common  munlock                 sys_munlock
 152    common  mlockall                sys_mlockall
index 17e81bd..734860a 100644 (file)
@@ -308,8 +308,8 @@ __SYSCALL(__NR_writev, compat_sys_writev)
 __SYSCALL(__NR_getsid, sys_getsid)
 #define __NR_fdatasync 148
 __SYSCALL(__NR_fdatasync, sys_fdatasync)
-#define __NR__sysctl 149
-__SYSCALL(__NR__sysctl, compat_sys_sysctl)
+                       /* 149 was sys_sysctl */
+__SYSCALL(149, sys_ni_syscall)
 #define __NR_mlock 150
 __SYSCALL(__NR_mlock, sys_mlock)
 #define __NR_munlock 151
index 75cbae6..7508b0a 100644 (file)
@@ -103,7 +103,8 @@ int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
        return ret;
 }
 
-static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
+                                                const struct vdso_data *vd)
 {
        u64 res;
 
index 9c29ad3..631ab12 100644 (file)
@@ -64,7 +64,8 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
        return ret;
 }
 
-static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
+                                                const struct vdso_data *vd)
 {
        u64 res;
 
index 1085089..779b697 100644 (file)
@@ -366,6 +366,15 @@ pgd_index (unsigned long address)
 }
 #define pgd_index pgd_index
 
+/*
+ * In the kernel's mapped region we know everything is in region number 5, so
+ * as an optimisation its PGD already points to the area for that region.
+ * However, this also means that we cannot use pgd_index() and we must
+ * never add the region here.
+ */
+#define pgd_offset_k(addr) \
+       (init_mm.pgd + (((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)))
+
 /* Look up a pgd entry in the gate area.  On IA-64, the gate-area
    resides in the kernel-mapped segment, hence we use pgd_offset_k()
    here.  */
index ced9c83..f52a41f 100644 (file)
 123    common  writev                          sys_writev
 124    common  pread64                         sys_pread64
 125    common  pwrite64                        sys_pwrite64
-126    common  _sysctl                         sys_sysctl
+126    common  _sysctl                         sys_ni_syscall
 127    common  mmap                            sys_mmap
 128    common  munmap                          sys_munmap
 129    common  mlock                           sys_mlock
index 6663f17..6f2f38d 100644 (file)
@@ -16,6 +16,7 @@ config M68K
        select HAVE_DEBUG_BUGVERBOSE
        select GENERIC_IRQ_SHOW
        select GENERIC_ATOMIC64
+       select NO_DMA if !MMU && !COLDFIRE
        select HAVE_UID16
        select VIRT_TO_BUS
        select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS
@@ -59,9 +60,6 @@ config TIME_LOW_RES
 config NO_IOPORT_MAP
        def_bool y
 
-config NO_DMA
-       def_bool (MMU && SUN3) || (!MMU && !COLDFIRE)
-
 config ZONE_DMA
        bool
        default y
index a82651d..17e8c3a 100644 (file)
@@ -126,6 +126,7 @@ config SUN3
        depends on MMU
        depends on !MMU_MOTOROLA
        select MMU_SUN3 if MMU
+       select NO_DMA
        select M68020
        help
          This option enables support for the Sun 3 series of workstations
index 1a4822d..81fc799 100644 (file)
 146    common  writev                          sys_writev
 147    common  getsid                          sys_getsid
 148    common  fdatasync                       sys_fdatasync
-149    common  _sysctl                         sys_sysctl
+149    common  _sysctl                         sys_ni_syscall
 150    common  mlock                           sys_mlock
 151    common  munlock                         sys_munlock
 152    common  mlockall                        sys_mlockall
index a3f4be8..b4e2639 100644 (file)
 146    common  writev                          sys_writev
 147    common  getsid                          sys_getsid
 148    common  fdatasync                       sys_fdatasync
-149    common  _sysctl                         sys_sysctl
+149    common  _sysctl                         sys_ni_syscall
 150    common  mlock                           sys_mlock
 151    common  munlock                         sys_munlock
 152    common  mlockall                        sys_mlockall
index 6b471cd..e924c81 100644 (file)
@@ -17,7 +17,6 @@ CONFIG_CGROUP_CPUACCT=y
 CONFIG_NAMESPACES=y
 CONFIG_USER_NS=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
 # CONFIG_VM_EVENT_COUNTERS is not set
index c63ddca..2203e2d 100644 (file)
@@ -167,7 +167,8 @@ static __always_inline u64 read_gic_count(const struct vdso_data *data)
 
 #endif
 
-static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
+                                                const struct vdso_data *vd)
 {
 #ifdef CONFIG_CSRC_R4K
        if (clock_mode == VDSO_CLOCKMODE_R4K)
@@ -175,7 +176,7 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
 #endif
 #ifdef CONFIG_CLKSRC_MIPS_GIC
        if (clock_mode == VDSO_CLOCKMODE_GIC)
-               return read_gic_count(get_vdso_data());
+               return read_gic_count(vd);
 #endif
        /*
         * Core checks mode already. So this raced against a concurrent
index 6b4ee92..f9df9ed 100644 (file)
 149    n32     munlockall                      sys_munlockall
 150    n32     vhangup                         sys_vhangup
 151    n32     pivot_root                      sys_pivot_root
-152    n32     _sysctl                         compat_sys_sysctl
+152    n32     _sysctl                         sys_ni_syscall
 153    n32     prctl                           sys_prctl
 154    n32     adjtimex                        sys_adjtimex_time32
 155    n32     setrlimit                       compat_sys_setrlimit
index 391acbf..557f995 100644 (file)
 149    n64     munlockall                      sys_munlockall
 150    n64     vhangup                         sys_vhangup
 151    n64     pivot_root                      sys_pivot_root
-152    n64     _sysctl                         sys_sysctl
+152    n64     _sysctl                         sys_ni_syscall
 153    n64     prctl                           sys_prctl
 154    n64     adjtimex                        sys_adjtimex
 155    n64     setrlimit                       sys_setrlimit
index 5727c51..195b43c 100644 (file)
 150    o32     unused150                       sys_ni_syscall
 151    o32     getsid                          sys_getsid
 152    o32     fdatasync                       sys_fdatasync
-153    o32     _sysctl                         sys_sysctl                      compat_sys_sysctl
+153    o32     _sysctl                         sys_ni_syscall
 154    o32     mlock                           sys_mlock
 155    o32     munlock                         sys_munlock
 156    o32     mlockall                        sys_mlockall
index db02fb2..7d6b4a7 100644 (file)
@@ -14,6 +14,8 @@
 #ifndef __ASM_OPENRISC_IO_H
 #define __ASM_OPENRISC_IO_H
 
+#include <linux/types.h>
+
 /*
  * PCI: can we really do 0 here if we have no port IO?
  */
 #define PIO_OFFSET             0
 #define PIO_MASK               0
 
-#include <asm-generic/io.h>
-
+#define ioremap ioremap
 void __iomem *ioremap(phys_addr_t offset, unsigned long size);
+
+#define iounmap iounmap
 extern void iounmap(void *addr);
 
+#include <asm-generic/io.h>
+
 #endif
index 48b6915..f039021 100644 (file)
 /* Ensure that the range from addr to addr+size is all within the process'
  * address space
  */
-#define __range_ok(addr, size) (size <= get_fs() && addr <= (get_fs()-size))
+static inline int __range_ok(unsigned long addr, unsigned long size)
+{
+       const mm_segment_t fs = get_fs();
 
-/* Ensure that addr is below task's addr_limit */
-#define __addr_ok(addr) ((unsigned long) addr < get_fs())
+       return size <= fs && addr <= (fs - size);
+}
 
 #define access_ok(addr, size)                                          \
 ({                                                                     \
-       unsigned long __ao_addr = (unsigned long)(addr);                \
-       unsigned long __ao_size = (unsigned long)(size);                \
-       __range_ok(__ao_addr, __ao_size);                               \
+       __chk_user_ptr(addr);                                           \
+       __range_ok((unsigned long)(addr), (size));                      \
 })
 
 /*
@@ -100,7 +101,7 @@ extern long __put_user_bad(void);
 #define __put_user_check(x, ptr, size)                                 \
 ({                                                                     \
        long __pu_err = -EFAULT;                                        \
-       __typeof__(*(ptr)) *__pu_addr = (ptr);                          \
+       __typeof__(*(ptr)) __user *__pu_addr = (ptr);                   \
        if (access_ok(__pu_addr, size))                 \
                __put_user_size((x), __pu_addr, (size), __pu_err);      \
        __pu_err;                                                       \
@@ -173,7 +174,7 @@ struct __large_struct {
 #define __get_user_check(x, ptr, size)                                 \
 ({                                                                     \
        long __gu_err = -EFAULT, __gu_val = 0;                          \
-       const __typeof__(*(ptr)) * __gu_addr = (ptr);                   \
+       const __typeof__(*(ptr)) __user *__gu_addr = (ptr);             \
        if (access_ok(__gu_addr, size))                 \
                __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                     \
@@ -241,17 +242,17 @@ raw_copy_from_user(void *to, const void __user *from, unsigned long size)
        return __copy_tofrom_user(to, (__force const void *)from, size);
 }
 static inline unsigned long
-raw_copy_to_user(void *to, const void __user *from, unsigned long size)
+raw_copy_to_user(void __user *to, const void *from, unsigned long size)
 {
        return __copy_tofrom_user((__force void *)to, from, size);
 }
 #define INLINE_COPY_FROM_USER
 #define INLINE_COPY_TO_USER
 
-extern unsigned long __clear_user(void *addr, unsigned long size);
+extern unsigned long __clear_user(void __user *addr, unsigned long size);
 
 static inline __must_check unsigned long
-clear_user(void *addr, unsigned long size)
+clear_user(void __user *addr, unsigned long size)
 {
        if (likely(access_ok(addr, size)))
                size = __clear_user(addr, size);
index 8aa438e..b18e775 100644 (file)
@@ -292,13 +292,15 @@ void __init setup_arch(char **cmdline_p)
        init_mm.brk = (unsigned long)_end;
 
 #ifdef CONFIG_BLK_DEV_INITRD
-       initrd_start = (unsigned long)&__initrd_start;
-       initrd_end = (unsigned long)&__initrd_end;
        if (initrd_start == initrd_end) {
+               printk(KERN_INFO "Initial ramdisk not found\n");
                initrd_start = 0;
                initrd_end = 0;
+       } else {
+               printk(KERN_INFO "Initial ramdisk at: 0x%p (%lu bytes)\n",
+                      (void *)(initrd_start), initrd_end - initrd_start);
+               initrd_below_start_ok = 1;
        }
-       initrd_below_start_ok = 1;
 #endif
 
        /* setup memblock allocator */
index 4f07548..97804f2 100644 (file)
@@ -68,7 +68,7 @@ static int restore_sigcontext(struct pt_regs *regs,
 
 asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
 {
-       struct rt_sigframe *frame = (struct rt_sigframe __user *)regs->sp;
+       struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->sp;
        sigset_t set;
 
        /*
@@ -76,7 +76,7 @@ asmlinkage long _sys_rt_sigreturn(struct pt_regs *regs)
         * then frame should be dword aligned here.  If it's
         * not, then the user is trying to mess with us.
         */
-       if (((long)frame) & 3)
+       if (((unsigned long)frame) & 3)
                goto badframe;
 
        if (!access_ok(frame, sizeof(*frame)))
@@ -151,7 +151,7 @@ static inline void __user *get_sigframe(struct ksignal *ksig,
 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
                          struct pt_regs *regs)
 {
-       struct rt_sigframe *frame;
+       struct rt_sigframe __user *frame;
        unsigned long return_ip;
        int err = 0;
 
@@ -181,10 +181,10 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
                l.ori r11,r0,__NR_sigreturn
                l.sys 1
         */
-       err |= __put_user(0xa960,             (short *)(frame->retcode + 0));
-       err |= __put_user(__NR_rt_sigreturn,  (short *)(frame->retcode + 2));
-       err |= __put_user(0x20000001, (unsigned long *)(frame->retcode + 4));
-       err |= __put_user(0x15000000, (unsigned long *)(frame->retcode + 8));
+       err |= __put_user(0xa960,             (short __user *)(frame->retcode + 0));
+       err |= __put_user(__NR_rt_sigreturn,  (short __user *)(frame->retcode + 2));
+       err |= __put_user(0x20000001, (unsigned long __user *)(frame->retcode + 4));
+       err |= __put_user(0x15000000, (unsigned long __user *)(frame->retcode + 8));
 
        if (err)
                return -EFAULT;
index bd1e660..29c82ef 100644 (file)
@@ -219,30 +219,99 @@ static inline void ipi_flush_tlb_all(void *ignored)
        local_flush_tlb_all();
 }
 
+static inline void ipi_flush_tlb_mm(void *info)
+{
+       struct mm_struct *mm = (struct mm_struct *)info;
+
+       local_flush_tlb_mm(mm);
+}
+
+static void smp_flush_tlb_mm(struct cpumask *cmask, struct mm_struct *mm)
+{
+       unsigned int cpuid;
+
+       if (cpumask_empty(cmask))
+               return;
+
+       cpuid = get_cpu();
+
+       if (cpumask_any_but(cmask, cpuid) >= nr_cpu_ids) {
+               /* local cpu is the only cpu present in cpumask */
+               local_flush_tlb_mm(mm);
+       } else {
+               on_each_cpu_mask(cmask, ipi_flush_tlb_mm, mm, 1);
+       }
+       put_cpu();
+}
+
+struct flush_tlb_data {
+       unsigned long addr1;
+       unsigned long addr2;
+};
+
+static inline void ipi_flush_tlb_page(void *info)
+{
+       struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
+
+       local_flush_tlb_page(NULL, fd->addr1);
+}
+
+static inline void ipi_flush_tlb_range(void *info)
+{
+       struct flush_tlb_data *fd = (struct flush_tlb_data *)info;
+
+       local_flush_tlb_range(NULL, fd->addr1, fd->addr2);
+}
+
+static void smp_flush_tlb_range(struct cpumask *cmask, unsigned long start,
+                               unsigned long end)
+{
+       unsigned int cpuid;
+
+       if (cpumask_empty(cmask))
+               return;
+
+       cpuid = get_cpu();
+
+       if (cpumask_any_but(cmask, cpuid) >= nr_cpu_ids) {
+               /* local cpu is the only cpu present in cpumask */
+               if ((end - start) <= PAGE_SIZE)
+                       local_flush_tlb_page(NULL, start);
+               else
+                       local_flush_tlb_range(NULL, start, end);
+       } else {
+               struct flush_tlb_data fd;
+
+               fd.addr1 = start;
+               fd.addr2 = end;
+
+               if ((end - start) <= PAGE_SIZE)
+                       on_each_cpu_mask(cmask, ipi_flush_tlb_page, &fd, 1);
+               else
+                       on_each_cpu_mask(cmask, ipi_flush_tlb_range, &fd, 1);
+       }
+       put_cpu();
+}
+
 void flush_tlb_all(void)
 {
        on_each_cpu(ipi_flush_tlb_all, NULL, 1);
 }
 
-/*
- * FIXME: implement proper functionality instead of flush_tlb_all.
- * *But*, as things currently stands, the local_tlb_flush_* functions will
- * all boil down to local_tlb_flush_all anyway.
- */
 void flush_tlb_mm(struct mm_struct *mm)
 {
-       on_each_cpu(ipi_flush_tlb_all, NULL, 1);
+       smp_flush_tlb_mm(mm_cpumask(mm), mm);
 }
 
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
 {
-       on_each_cpu(ipi_flush_tlb_all, NULL, 1);
+       smp_flush_tlb_range(mm_cpumask(vma->vm_mm), uaddr, uaddr + PAGE_SIZE);
 }
 
 void flush_tlb_range(struct vm_area_struct *vma,
                     unsigned long start, unsigned long end)
 {
-       on_each_cpu(ipi_flush_tlb_all, NULL, 1);
+       smp_flush_tlb_range(mm_cpumask(vma->vm_mm), start, end);
 }
 
 /* Instruction cache invalidate - performed on each cpu */
index 43f140a..54d3880 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/export.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
+#include <linux/sched/task_stack.h>
 #include <linux/stacktrace.h>
 
 #include <asm/processor.h>
@@ -68,12 +69,25 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
        unsigned long *sp = NULL;
 
+       if (!try_get_task_stack(tsk))
+               return;
+
        if (tsk == current)
                sp = (unsigned long *) &sp;
-       else
-               sp = (unsigned long *) KSTK_ESP(tsk);
+       else {
+               unsigned long ksp;
+
+               /* Locate stack from kernel context */
+               ksp = task_thread_info(tsk)->ksp;
+               ksp += STACK_FRAME_OVERHEAD;    /* redzone */
+               ksp += sizeof(struct pt_regs);
+
+               sp = (unsigned long *) ksp;
+       }
 
        unwind_stack(trace, sp, save_stack_address_nosched);
+
+       put_task_stack(tsk);
 }
 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
 
index 60449fd..22fbc5f 100644 (file)
@@ -96,18 +96,6 @@ SECTIONS
 
         __init_end = .;
 
-       . = ALIGN(PAGE_SIZE);
-       .initrd                 : AT(ADDR(.initrd) - LOAD_OFFSET)
-       {
-               __initrd_start = .;
-               *(.initrd)
-               __initrd_end = .;
-               FILL (0);
-                . = ALIGN (PAGE_SIZE);
-       }
-
-        __vmlinux_end = .;            /* last address of the physical file */
-
        BSS_SECTION(0, 0, 0x20)
 
         _end = .;
index 4b680ae..2b6feab 100644 (file)
@@ -137,21 +137,28 @@ void local_flush_tlb_mm(struct mm_struct *mm)
 void switch_mm(struct mm_struct *prev, struct mm_struct *next,
               struct task_struct *next_tsk)
 {
+       unsigned int cpu;
+
+       if (unlikely(prev == next))
+               return;
+
+       cpu = smp_processor_id();
+
+       cpumask_clear_cpu(cpu, mm_cpumask(prev));
+       cpumask_set_cpu(cpu, mm_cpumask(next));
+
        /* remember the pgd for the fault handlers
         * this is similar to the pgd register in some other CPU's.
         * we need our own copy of it because current and active_mm
         * might be invalid at points where we still need to derefer
         * the pgd.
         */
-       current_pgd[smp_processor_id()] = next->pgd;
+       current_pgd[cpu] = next->pgd;
 
        /* We don't have context support implemented, so flush all
         * entries belonging to previous map
         */
-
-       if (prev != next)
-               local_flush_tlb_mm(prev);
-
+       local_flush_tlb_mm(prev);
 }
 
 /*
index 116effe..45e20d3 100644 (file)
@@ -303,8 +303,8 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
 #define ioread64be ioread64be
 #define iowrite64 iowrite64
 #define iowrite64be iowrite64be
-extern u64 ioread64(void __iomem *addr);
-extern u64 ioread64be(void __iomem *addr);
+extern u64 ioread64(const void __iomem *addr);
+extern u64 ioread64be(const void __iomem *addr);
 extern void iowrite64(u64 val, void __iomem *addr);
 extern void iowrite64be(u64 val, void __iomem *addr);
 
index cc7ecc2..a6482b2 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <asm/cache.h>
 
+#define __HAVE_ARCH_PMD_ALLOC_ONE
 #define __HAVE_ARCH_PMD_FREE
 #define __HAVE_ARCH_PGD_FREE
 #include <asm-generic/pgalloc.h>
@@ -67,6 +68,11 @@ static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
                        (__u32)(__pa((unsigned long)pmd) >> PxD_VALUE_SHIFT)));
 }
 
+static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+       return (pmd_t *)__get_free_pages(GFP_PGTABLE_KERNEL, PMD_ORDER);
+}
+
 static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 {
        if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED) {
index 292baab..def64d2 100644 (file)
 146    common  writev                  sys_writev                      compat_sys_writev
 147    common  getsid                  sys_getsid
 148    common  fdatasync               sys_fdatasync
-149    common  _sysctl                 sys_sysctl                      compat_sys_sysctl
+149    common  _sysctl                 sys_ni_syscall
 150    common  mlock                   sys_mlock
 151    common  munlock                 sys_munlock
 152    common  mlockall                sys_mlockall
index 0195aec..ce40041 100644 (file)
 #endif
 
 struct iomap_ops {
-       unsigned int (*read8)(void __iomem *);
-       unsigned int (*read16)(void __iomem *);
-       unsigned int (*read16be)(void __iomem *);
-       unsigned int (*read32)(void __iomem *);
-       unsigned int (*read32be)(void __iomem *);
-       u64 (*read64)(void __iomem *);
-       u64 (*read64be)(void __iomem *);
+       unsigned int (*read8)(const void __iomem *);
+       unsigned int (*read16)(const void __iomem *);
+       unsigned int (*read16be)(const void __iomem *);
+       unsigned int (*read32)(const void __iomem *);
+       unsigned int (*read32be)(const void __iomem *);
+       u64 (*read64)(const void __iomem *);
+       u64 (*read64be)(const void __iomem *);
        void (*write8)(u8, void __iomem *);
        void (*write16)(u16, void __iomem *);
        void (*write16be)(u16, void __iomem *);
@@ -57,9 +57,9 @@ struct iomap_ops {
        void (*write32be)(u32, void __iomem *);
        void (*write64)(u64, void __iomem *);
        void (*write64be)(u64, void __iomem *);
-       void (*read8r)(void __iomem *, void *, unsigned long);
-       void (*read16r)(void __iomem *, void *, unsigned long);
-       void (*read32r)(void __iomem *, void *, unsigned long);
+       void (*read8r)(const void __iomem *, void *, unsigned long);
+       void (*read16r)(const void __iomem *, void *, unsigned long);
+       void (*read32r)(const void __iomem *, void *, unsigned long);
        void (*write8r)(void __iomem *, const void *, unsigned long);
        void (*write16r)(void __iomem *, const void *, unsigned long);
        void (*write32r)(void __iomem *, const void *, unsigned long);
@@ -69,17 +69,17 @@ struct iomap_ops {
 
 #define ADDR2PORT(addr) ((unsigned long __force)(addr) & 0xffffff)
 
-static unsigned int ioport_read8(void __iomem *addr)
+static unsigned int ioport_read8(const void __iomem *addr)
 {
        return inb(ADDR2PORT(addr));
 }
 
-static unsigned int ioport_read16(void __iomem *addr)
+static unsigned int ioport_read16(const void __iomem *addr)
 {
        return inw(ADDR2PORT(addr));
 }
 
-static unsigned int ioport_read32(void __iomem *addr)
+static unsigned int ioport_read32(const void __iomem *addr)
 {
        return inl(ADDR2PORT(addr));
 }
@@ -99,17 +99,17 @@ static void ioport_write32(u32 datum, void __iomem *addr)
        outl(datum, ADDR2PORT(addr));
 }
 
-static void ioport_read8r(void __iomem *addr, void *dst, unsigned long count)
+static void ioport_read8r(const void __iomem *addr, void *dst, unsigned long count)
 {
        insb(ADDR2PORT(addr), dst, count);
 }
 
-static void ioport_read16r(void __iomem *addr, void *dst, unsigned long count)
+static void ioport_read16r(const void __iomem *addr, void *dst, unsigned long count)
 {
        insw(ADDR2PORT(addr), dst, count);
 }
 
-static void ioport_read32r(void __iomem *addr, void *dst, unsigned long count)
+static void ioport_read32r(const void __iomem *addr, void *dst, unsigned long count)
 {
        insl(ADDR2PORT(addr), dst, count);
 }
@@ -150,37 +150,37 @@ static const struct iomap_ops ioport_ops = {
 
 /* Legacy I/O memory ops */
 
-static unsigned int iomem_read8(void __iomem *addr)
+static unsigned int iomem_read8(const void __iomem *addr)
 {
        return readb(addr);
 }
 
-static unsigned int iomem_read16(void __iomem *addr)
+static unsigned int iomem_read16(const void __iomem *addr)
 {
        return readw(addr);
 }
 
-static unsigned int iomem_read16be(void __iomem *addr)
+static unsigned int iomem_read16be(const void __iomem *addr)
 {
        return __raw_readw(addr);
 }
 
-static unsigned int iomem_read32(void __iomem *addr)
+static unsigned int iomem_read32(const void __iomem *addr)
 {
        return readl(addr);
 }
 
-static unsigned int iomem_read32be(void __iomem *addr)
+static unsigned int iomem_read32be(const void __iomem *addr)
 {
        return __raw_readl(addr);
 }
 
-static u64 iomem_read64(void __iomem *addr)
+static u64 iomem_read64(const void __iomem *addr)
 {
        return readq(addr);
 }
 
-static u64 iomem_read64be(void __iomem *addr)
+static u64 iomem_read64be(const void __iomem *addr)
 {
        return __raw_readq(addr);
 }
@@ -220,7 +220,7 @@ static void iomem_write64be(u64 datum, void __iomem *addr)
        __raw_writel(datum, addr);
 }
 
-static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count)
+static void iomem_read8r(const void __iomem *addr, void *dst, unsigned long count)
 {
        while (count--) {
                *(u8 *)dst = __raw_readb(addr);
@@ -228,7 +228,7 @@ static void iomem_read8r(void __iomem *addr, void *dst, unsigned long count)
        }
 }
 
-static void iomem_read16r(void __iomem *addr, void *dst, unsigned long count)
+static void iomem_read16r(const void __iomem *addr, void *dst, unsigned long count)
 {
        while (count--) {
                *(u16 *)dst = __raw_readw(addr);
@@ -236,7 +236,7 @@ static void iomem_read16r(void __iomem *addr, void *dst, unsigned long count)
        }
 }
 
-static void iomem_read32r(void __iomem *addr, void *dst, unsigned long count)
+static void iomem_read32r(const void __iomem *addr, void *dst, unsigned long count)
 {
        while (count--) {
                *(u32 *)dst = __raw_readl(addr);
@@ -297,49 +297,49 @@ static const struct iomap_ops *iomap_ops[8] = {
 };
 
 
-unsigned int ioread8(void __iomem *addr)
+unsigned int ioread8(const void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr)))
                return iomap_ops[ADDR_TO_REGION(addr)]->read8(addr);
        return *((u8 *)addr);
 }
 
-unsigned int ioread16(void __iomem *addr)
+unsigned int ioread16(const void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr)))
                return iomap_ops[ADDR_TO_REGION(addr)]->read16(addr);
        return le16_to_cpup((u16 *)addr);
 }
 
-unsigned int ioread16be(void __iomem *addr)
+unsigned int ioread16be(const void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr)))
                return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr);
        return *((u16 *)addr);
 }
 
-unsigned int ioread32(void __iomem *addr)
+unsigned int ioread32(const void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr)))
                return iomap_ops[ADDR_TO_REGION(addr)]->read32(addr);
        return le32_to_cpup((u32 *)addr);
 }
 
-unsigned int ioread32be(void __iomem *addr)
+unsigned int ioread32be(const void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr)))
                return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr);
        return *((u32 *)addr);
 }
 
-u64 ioread64(void __iomem *addr)
+u64 ioread64(const void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr)))
                return iomap_ops[ADDR_TO_REGION(addr)]->read64(addr);
        return le64_to_cpup((u64 *)addr);
 }
 
-u64 ioread64be(void __iomem *addr)
+u64 ioread64be(const void __iomem *addr)
 {
        if (unlikely(INDIRECT_ADDR(addr)))
                return iomap_ops[ADDR_TO_REGION(addr)]->read64be(addr);
@@ -411,7 +411,7 @@ void iowrite64be(u64 datum, void __iomem *addr)
 
 /* Repeating interfaces */
 
-void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        if (unlikely(INDIRECT_ADDR(addr))) {
                iomap_ops[ADDR_TO_REGION(addr)]->read8r(addr, dst, count);
@@ -423,7 +423,7 @@ void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
        }
 }
 
-void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        if (unlikely(INDIRECT_ADDR(addr))) {
                iomap_ops[ADDR_TO_REGION(addr)]->read16r(addr, dst, count);
@@ -435,7 +435,7 @@ void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
        }
 }
 
-void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        if (unlikely(INDIRECT_ADDR(addr))) {
                iomap_ops[ADDR_TO_REGION(addr)]->read32r(addr, dst, count);
index 5ac84ef..9fe4fb3 100644 (file)
  * Here comes the ppc64 implementation of the IOMAP 
  * interfaces.
  */
-unsigned int ioread8(void __iomem *addr)
+unsigned int ioread8(const void __iomem *addr)
 {
        return readb(addr);
 }
-unsigned int ioread16(void __iomem *addr)
+unsigned int ioread16(const void __iomem *addr)
 {
        return readw(addr);
 }
-unsigned int ioread16be(void __iomem *addr)
+unsigned int ioread16be(const void __iomem *addr)
 {
        return readw_be(addr);
 }
-unsigned int ioread32(void __iomem *addr)
+unsigned int ioread32(const void __iomem *addr)
 {
        return readl(addr);
 }
-unsigned int ioread32be(void __iomem *addr)
+unsigned int ioread32be(const void __iomem *addr)
 {
        return readl_be(addr);
 }
@@ -41,27 +41,27 @@ EXPORT_SYMBOL(ioread16be);
 EXPORT_SYMBOL(ioread32);
 EXPORT_SYMBOL(ioread32be);
 #ifdef __powerpc64__
-u64 ioread64(void __iomem *addr)
+u64 ioread64(const void __iomem *addr)
 {
        return readq(addr);
 }
-u64 ioread64_lo_hi(void __iomem *addr)
+u64 ioread64_lo_hi(const void __iomem *addr)
 {
        return readq(addr);
 }
-u64 ioread64_hi_lo(void __iomem *addr)
+u64 ioread64_hi_lo(const void __iomem *addr)
 {
        return readq(addr);
 }
-u64 ioread64be(void __iomem *addr)
+u64 ioread64be(const void __iomem *addr)
 {
        return readq_be(addr);
 }
-u64 ioread64be_lo_hi(void __iomem *addr)
+u64 ioread64be_lo_hi(const void __iomem *addr)
 {
        return readq_be(addr);
 }
-u64 ioread64be_hi_lo(void __iomem *addr)
+u64 ioread64be_hi_lo(const void __iomem *addr)
 {
        return readq_be(addr);
 }
@@ -139,15 +139,15 @@ EXPORT_SYMBOL(iowrite64be_hi_lo);
  * FIXME! We could make these do EEH handling if we really
  * wanted. Not clear if we do.
  */
-void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        readsb(addr, dst, count);
 }
-void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        readsw(addr, dst, count);
 }
-void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        readsl(addr, dst, count);
 }
index be9f745..c2d737f 100644 (file)
 146    common  writev                          sys_writev                      compat_sys_writev
 147    common  getsid                          sys_getsid
 148    common  fdatasync                       sys_fdatasync
-149    nospu   _sysctl                         sys_sysctl                      compat_sys_sysctl
+149    nospu   _sysctl                         sys_ni_syscall
 150    common  mlock                           sys_mlock
 151    common  munlock                         sys_munlock
 152    common  mlockall                        sys_mlockall
index 1478fce..1da9dbb 100644 (file)
@@ -1115,9 +1115,8 @@ void hash__early_init_mmu_secondary(void)
                        && cpu_has_feature(CPU_FTR_HVMODE))
                tlbiel_all();
 
-#ifdef CONFIG_PPC_MEM_KEYS
-       mtspr(SPRN_UAMOR, default_uamor);
-#endif
+       if (IS_ENABLED(CONFIG_PPC_MEM_KEYS) && mmu_has_feature(MMU_FTR_PKEY))
+               mtspr(SPRN_UAMOR, default_uamor);
 }
 #endif /* CONFIG_SMP */
 
index 69a6b87..b1d091a 100644 (file)
@@ -73,12 +73,6 @@ static int scan_pkey_feature(void)
        if (early_radix_enabled())
                return 0;
 
-       /*
-        * Only P7 and above supports SPRN_AMR update with MSR[PR] = 1
-        */
-       if (!early_cpu_has_feature(CPU_FTR_ARCH_206))
-               return 0;
-
        ret = of_scan_flat_dt(dt_scan_storage_keys, &pkeys_total);
        if (ret == 0) {
                /*
@@ -124,6 +118,12 @@ void __init pkey_early_init_devtree(void)
                     __builtin_popcountl(ARCH_VM_PKEY_FLAGS >> VM_PKEY_SHIFT)
                                != (sizeof(u64) * BITS_PER_BYTE));
 
+       /*
+        * Only P7 and above supports SPRN_AMR update with MSR[PR] = 1
+        */
+       if (!early_cpu_has_feature(CPU_FTR_ARCH_206))
+               return;
+
        /* scan the device tree for pkey feature */
        pkeys_total = scan_pkey_feature();
        if (!pkeys_total)
index 3099362..f839f16 100644 (file)
@@ -60,7 +60,8 @@ int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
        return ret;
 }
 
-static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode,
+                                                const struct vdso_data *vd)
 {
        /*
         * The purpose of csr_read(CSR_TIME) is to trap the system into
index d0c5c31..0a4e81b 100644 (file)
@@ -77,16 +77,10 @@ relocate:
        csrw CSR_SATP, a0
 .align 2
 1:
-       /* Set trap vector to exception handler */
-       la a0, handle_exception
+       /* Set trap vector to spin forever to help debug */
+       la a0, .Lsecondary_park
        csrw CSR_TVEC, a0
 
-       /*
-        * Set sup0 scratch register to 0, indicating to exception vector that
-        * we are presently executing in kernel.
-        */
-       csrw CSR_SCRATCH, zero
-
        /* Reload the global pointer */
 .option push
 .option norelax
@@ -144,9 +138,23 @@ secondary_start_common:
        la a0, swapper_pg_dir
        call relocate
 #endif
+       call setup_trap_vector
        tail smp_callin
 #endif /* CONFIG_SMP */
 
+.align 2
+setup_trap_vector:
+       /* Set trap vector to exception handler */
+       la a0, handle_exception
+       csrw CSR_TVEC, a0
+
+       /*
+        * Set sup0 scratch register to 0, indicating to exception vector that
+        * we are presently executing in kernel.
+        */
+       csrw CSR_SCRATCH, zero
+       ret
+
 .Lsecondary_park:
        /* We lack SMP support or have too many harts, so park this hart */
        wfi
@@ -240,6 +248,7 @@ clear_bss_done:
        call relocate
 #endif /* CONFIG_MMU */
 
+       call setup_trap_vector
        /* Restore C environment */
        la tp, init_task
        sw zero, TASK_TI_CPU(tp)
index f1fda43..10456bc 100644 (file)
 146  common    writev                  sys_writev                      compat_sys_writev
 147  common    getsid                  sys_getsid                      sys_getsid
 148  common    fdatasync               sys_fdatasync                   sys_fdatasync
-149  common    _sysctl                 sys_sysctl                      compat_sys_sysctl
+149  common    _sysctl                 -                               -
 150  common    mlock                   sys_mlock                       sys_mlock
 151  common    munlock                 sys_munlock                     sys_munlock
 152  common    mlockall                sys_mlockall                    sys_mlockall
index 9fc2b01..d209271 100644 (file)
@@ -1,75 +1,77 @@
 # SPDX-License-Identifier: GPL-2.0
 config SUPERH
        def_bool y
+       select ARCH_32BIT_OFF_T
+       select ARCH_HAVE_CUSTOM_GPIO_H
+       select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
        select ARCH_HAS_BINFMT_FLAT if !MMU
+       select ARCH_HAS_GIGANTIC_PAGE
+       select ARCH_HAS_GCOV_PROFILE_ALL
        select ARCH_HAS_PTE_SPECIAL
        select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
+       select ARCH_HIBERNATION_POSSIBLE if MMU
        select ARCH_MIGHT_HAVE_PC_PARPORT
-       select HAVE_PATA_PLATFORM
+       select ARCH_WANT_IPC_PARSE_VERSION
        select CLKDEV_LOOKUP
+       select CPU_NO_EFFICIENT_FFS
        select DMA_DECLARE_COHERENT
-       select HAVE_IDE if HAS_IOPORT_MAP
-       select HAVE_OPROFILE
+       select GENERIC_ATOMIC64
+       select GENERIC_CLOCKEVENTS
+       select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST
+       select GENERIC_IDLE_POLL_SETUP
+       select GENERIC_IRQ_SHOW
+       select GENERIC_PCI_IOMAP if PCI
+       select GENERIC_SCHED_CLOCK
+       select GENERIC_STRNCPY_FROM_USER
+       select GENERIC_STRNLEN_USER
+       select GENERIC_SMP_IDLE_THREAD
+       select GUP_GET_PTE_LOW_HIGH if X2TLB
+       select HAVE_ARCH_AUDITSYSCALL
+       select HAVE_ARCH_KGDB
+       select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_TRACEHOOK
-       select HAVE_PERF_EVENTS
+       select HAVE_COPY_THREAD_TLS
        select HAVE_DEBUG_BUGVERBOSE
-       select HAVE_FAST_GUP if MMU
-       select ARCH_HAVE_CUSTOM_GPIO_H
-       select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A)
-       select ARCH_HAS_GCOV_PROFILE_ALL
-       select PERF_USE_VMALLOC
        select HAVE_DEBUG_KMEMLEAK
-       select HAVE_KERNEL_GZIP
-       select CPU_NO_EFFICIENT_FFS
+       select HAVE_DYNAMIC_FTRACE
+       select HAVE_FAST_GUP if MMU
+       select HAVE_FUNCTION_GRAPH_TRACER
+       select HAVE_FUNCTION_TRACER
+       select HAVE_FUTEX_CMPXCHG if FUTEX
+       select HAVE_FTRACE_MCOUNT_RECORD
+       select HAVE_HW_BREAKPOINT
+       select HAVE_IDE if HAS_IOPORT_MAP
+       select HAVE_IOREMAP_PROT if MMU && !X2TLB
        select HAVE_KERNEL_BZIP2
+       select HAVE_KERNEL_GZIP
        select HAVE_KERNEL_LZMA
-       select HAVE_KERNEL_XZ
        select HAVE_KERNEL_LZO
+       select HAVE_KERNEL_XZ
+       select HAVE_KPROBES
+       select HAVE_KRETPROBES
+       select HAVE_MIXED_BREAKPOINTS_REGS
+       select HAVE_MOD_ARCH_SPECIFIC if DWARF_UNWINDER
+       select HAVE_NMI
+       select HAVE_OPROFILE
+       select HAVE_PATA_PLATFORM
+       select HAVE_PERF_EVENTS
+       select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_UID16
-       select ARCH_WANT_IPC_PARSE_VERSION
+       select HAVE_STACKPROTECTOR
        select HAVE_SYSCALL_TRACEPOINTS
-       select HAVE_REGS_AND_STACK_ACCESS_API
-       select MAY_HAVE_SPARSE_IRQ
        select IRQ_FORCED_THREADING
-       select RTC_LIB
-       select GENERIC_ATOMIC64
-       select GENERIC_IRQ_SHOW
-       select GENERIC_SMP_IDLE_THREAD
-       select GENERIC_IDLE_POLL_SETUP
-       select GENERIC_CLOCKEVENTS
-       select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST
-       select GENERIC_PCI_IOMAP if PCI
-       select GENERIC_SCHED_CLOCK
-       select GENERIC_STRNCPY_FROM_USER
-       select GENERIC_STRNLEN_USER
-       select HAVE_MOD_ARCH_SPECIFIC if DWARF_UNWINDER
+       select MAY_HAVE_SPARSE_IRQ
        select MODULES_USE_ELF_RELA
+       select NEED_SG_DMA_LENGTH
+       select NO_DMA if !MMU && !DMA_COHERENT
        select NO_GENERIC_PCI_IOPORT_MAP if PCI
-       select OLD_SIGSUSPEND
        select OLD_SIGACTION
+       select OLD_SIGSUSPEND
        select PCI_DOMAINS if PCI
-       select HAVE_ARCH_AUDITSYSCALL
-       select HAVE_FUTEX_CMPXCHG if FUTEX
-       select HAVE_NMI
-       select NEED_SG_DMA_LENGTH
-       select ARCH_HAS_GIGANTIC_PAGE
-       select ARCH_32BIT_OFF_T
-       select GUP_GET_PTE_LOW_HIGH if X2TLB
-       select HAVE_KPROBES
-       select HAVE_KRETPROBES
-       select HAVE_IOREMAP_PROT if MMU && !X2TLB
-       select HAVE_FUNCTION_TRACER
-       select HAVE_FTRACE_MCOUNT_RECORD
-       select HAVE_DYNAMIC_FTRACE
-       select ARCH_WANT_IPC_PARSE_VERSION
-       select HAVE_FUNCTION_GRAPH_TRACER
-       select HAVE_ARCH_KGDB
-       select HAVE_HW_BREAKPOINT
-       select HAVE_MIXED_BREAKPOINTS_REGS
        select PERF_EVENTS
-       select ARCH_HIBERNATION_POSSIBLE if MMU
+       select PERF_USE_VMALLOC
+       select RTC_LIB
        select SPARSE_IRQ
-       select HAVE_STACKPROTECTOR
        help
          The SuperH is a RISC processor targeted for use in embedded systems
          and consumer electronics; it was also used in the Sega Dreamcast
@@ -123,8 +125,8 @@ config ARCH_HAS_ILOG2_U64
 
 config NO_IOPORT_MAP
        def_bool !PCI
-       depends on !SH_CAYMAN && !SH_SH4202_MICRODEV && !SH_SHMIN && \
-                  !SH_HP6XX && !SH_SOLUTION_ENGINE
+       depends on !SH_SH4202_MICRODEV && !SH_SHMIN && !SH_HP6XX && \
+                  !SH_SOLUTION_ENGINE
 
 config IO_TRAPPED
        bool
@@ -136,8 +138,10 @@ config DMA_COHERENT
        bool
 
 config DMA_NONCOHERENT
-       def_bool !DMA_COHERENT
+       def_bool !NO_DMA && !DMA_COHERENT
+       select ARCH_HAS_DMA_PREP_COHERENT
        select ARCH_HAS_SYNC_DMA_FOR_DEVICE
+       select DMA_DIRECT_REMAP
 
 config PGTABLE_LEVELS
        default 3 if X2TLB
@@ -630,7 +634,7 @@ config SMP
          Y to "Enhanced Real Time Clock Support", below.
 
          See also <file:Documentation/admin-guide/lockup-watchdogs.rst> and the SMP-HOWTO
-         available at <http://www.tldp.org/docs.html#howto>.
+         available at <https://www.tldp.org/docs.html#howto>.
 
          If you don't know what to do here, say N.
 
@@ -726,7 +730,6 @@ config ZERO_PAGE_OFFSET
 config BOOT_LINK_OFFSET
        hex
        default "0x00210000" if SH_SHMIN
-       default "0x00400000" if SH_CAYMAN
        default "0x00810000" if SH_7780_SOLUTION_ENGINE
        default "0x009e0000" if SH_TITAN
        default "0x01800000" if SH_SDK7780
index da9cf95..2faebfd 100644 (file)
@@ -15,11 +15,7 @@ ifneq ($(SUBARCH),$(ARCH))
   endif
 endif
 
-ifeq ($(ARCH),sh)
 KBUILD_DEFCONFIG       := shx3_defconfig
-else
-KBUILD_DEFCONFIG       := cayman_defconfig
-endif
 
 isa-y                                  := any
 isa-$(CONFIG_SH_DSP)                   := sh
@@ -143,7 +139,6 @@ machdir-$(CONFIG_SH_SH7763RDP)                      += mach-sh7763rdp
 machdir-$(CONFIG_SH_SH4202_MICRODEV)           += mach-microdev
 machdir-$(CONFIG_SH_LANDISK)                   += mach-landisk
 machdir-$(CONFIG_SH_LBOX_RE2)                  += mach-lboxre2
-machdir-$(CONFIG_SH_CAYMAN)                    += mach-cayman
 machdir-$(CONFIG_SH_RSK)                       += mach-rsk
 
 ifneq ($(machdir-y),)
index fb0ca0c..83bcb6d 100644 (file)
@@ -340,12 +340,6 @@ config SH_MAGIC_PANEL_R2
        help
          Select Magic Panel R2 if configuring for Magic Panel R2.
 
-config SH_CAYMAN
-       bool "Hitachi Cayman"
-       depends on CPU_SUBTYPE_SH5_101 || CPU_SUBTYPE_SH5_103
-       select HAVE_PCI
-       select ARCH_MIGHT_HAVE_PC_SERIO
-
 config SH_POLARIS
        bool "SMSC Polaris"
        select CPU_HAS_IPR_IRQ
index ef9c87d..6ea85e4 100644 (file)
@@ -126,14 +126,14 @@ static void __init sh2007_init_irq(void)
  */
 static void __init sh2007_setup(char **cmdline_p)
 {
-       printk(KERN_INFO "SH-2007 Setup...");
+       pr_info("SH-2007 Setup...");
 
        /* setup wait control registers for area 5 */
        __raw_writel(CS5BCR_D, CS5BCR);
        __raw_writel(CS5WCR_D, CS5WCR);
        __raw_writel(CS5PCR_D, CS5PCR);
 
-       printk(KERN_INFO " done.\n");
+       pr_cont(" done.\n");
 }
 
 /*
diff --git a/arch/sh/boards/mach-cayman/Makefile b/arch/sh/boards/mach-cayman/Makefile
deleted file mode 100644 (file)
index 775a4be..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-# SPDX-License-Identifier: GPL-2.0
-#
-# Makefile for the Hitachi Cayman specific parts of the kernel
-#
-obj-y := setup.o irq.o panic.o
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
deleted file mode 100644 (file)
index 0305d0b..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/sh/mach-cayman/irq.c - SH-5 Cayman Interrupt Support
- *
- * This file handles the board specific parts of the Cayman interrupt system
- *
- * Copyright (C) 2002 Stuart Menefy
- */
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/signal.h>
-#include <cpu/irq.h>
-#include <asm/page.h>
-
-/* Setup for the SMSC FDC37C935 / LAN91C100FD */
-#define SMSC_IRQ         IRQ_IRL1
-
-/* Setup for PCI Bus 2, which transmits interrupts via the EPLD */
-#define PCI2_IRQ         IRQ_IRL3
-
-unsigned long epld_virt;
-
-#define EPLD_BASE        0x04002000
-#define EPLD_STATUS_BASE (epld_virt + 0x10)
-#define EPLD_MASK_BASE   (epld_virt + 0x20)
-
-/* Note the SMSC SuperIO chip and SMSC LAN chip interrupts are all muxed onto
-   the same SH-5 interrupt */
-
-static irqreturn_t cayman_interrupt_smsc(int irq, void *dev_id)
-{
-        printk(KERN_INFO "CAYMAN: spurious SMSC interrupt\n");
-       return IRQ_NONE;
-}
-
-static irqreturn_t cayman_interrupt_pci2(int irq, void *dev_id)
-{
-        printk(KERN_INFO "CAYMAN: spurious PCI interrupt, IRQ %d\n", irq);
-       return IRQ_NONE;
-}
-
-static void enable_cayman_irq(struct irq_data *data)
-{
-       unsigned int irq = data->irq;
-       unsigned long flags;
-       unsigned long mask;
-       unsigned int reg;
-       unsigned char bit;
-
-       irq -= START_EXT_IRQS;
-       reg = EPLD_MASK_BASE + ((irq / 8) << 2);
-       bit = 1<<(irq % 8);
-       local_irq_save(flags);
-       mask = __raw_readl(reg);
-       mask |= bit;
-       __raw_writel(mask, reg);
-       local_irq_restore(flags);
-}
-
-static void disable_cayman_irq(struct irq_data *data)
-{
-       unsigned int irq = data->irq;
-       unsigned long flags;
-       unsigned long mask;
-       unsigned int reg;
-       unsigned char bit;
-
-       irq -= START_EXT_IRQS;
-       reg = EPLD_MASK_BASE + ((irq / 8) << 2);
-       bit = 1<<(irq % 8);
-       local_irq_save(flags);
-       mask = __raw_readl(reg);
-       mask &= ~bit;
-       __raw_writel(mask, reg);
-       local_irq_restore(flags);
-}
-
-struct irq_chip cayman_irq_type = {
-       .name           = "Cayman-IRQ",
-       .irq_unmask     = enable_cayman_irq,
-       .irq_mask       = disable_cayman_irq,
-};
-
-int cayman_irq_demux(int evt)
-{
-       int irq = intc_evt_to_irq[evt];
-
-       if (irq == SMSC_IRQ) {
-               unsigned long status;
-               int i;
-
-               status = __raw_readl(EPLD_STATUS_BASE) &
-                        __raw_readl(EPLD_MASK_BASE) & 0xff;
-               if (status == 0) {
-                       irq = -1;
-               } else {
-                       for (i=0; i<8; i++) {
-                               if (status & (1<<i))
-                                       break;
-                       }
-                       irq = START_EXT_IRQS + i;
-               }
-       }
-
-       if (irq == PCI2_IRQ) {
-               unsigned long status;
-               int i;
-
-               status = __raw_readl(EPLD_STATUS_BASE + 3 * sizeof(u32)) &
-                        __raw_readl(EPLD_MASK_BASE + 3 * sizeof(u32)) & 0xff;
-               if (status == 0) {
-                       irq = -1;
-               } else {
-                       for (i=0; i<8; i++) {
-                               if (status & (1<<i))
-                                       break;
-                       }
-                       irq = START_EXT_IRQS + (3 * 8) + i;
-               }
-       }
-
-       return irq;
-}
-
-void init_cayman_irq(void)
-{
-       int i;
-
-       epld_virt = (unsigned long)ioremap(EPLD_BASE, 1024);
-       if (!epld_virt) {
-               printk(KERN_ERR "Cayman IRQ: Unable to remap EPLD\n");
-               return;
-       }
-
-       for (i = 0; i < NR_EXT_IRQS; i++) {
-               irq_set_chip_and_handler(START_EXT_IRQS + i,
-                                        &cayman_irq_type, handle_level_irq);
-       }
-
-       /* Setup the SMSC interrupt */
-       if (request_irq(SMSC_IRQ, cayman_interrupt_smsc, 0, "Cayman SMSC Mux",
-                       NULL))
-               pr_err("Failed to register Cayman SMSC Mux interrupt\n");
-       if (request_irq(PCI2_IRQ, cayman_interrupt_pci2, 0, "Cayman PCI2 Mux",
-                       NULL))
-               pr_err("Failed to register Cayman PCI2 Mux interrupt\n");
-}
diff --git a/arch/sh/boards/mach-cayman/panic.c b/arch/sh/boards/mach-cayman/panic.c
deleted file mode 100644 (file)
index cfc4631..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Copyright (C) 2003  Richard Curnow, SuperH UK Limited
- */
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <cpu/registers.h>
-
-/* THIS IS A PHYSICAL ADDRESS */
-#define HDSP2534_ADDR (0x04002100)
-
-static void poor_mans_delay(void)
-{
-       int i;
-
-       for (i = 0; i < 2500000; i++)
-               cpu_relax();
-}
-
-static void show_value(unsigned long x)
-{
-       int i;
-       unsigned nibble;
-       for (i = 0; i < 8; i++) {
-               nibble = ((x >> (i * 4)) & 0xf);
-
-               __raw_writeb(nibble + ((nibble > 9) ? 55 : 48),
-                         HDSP2534_ADDR + 0xe0 + ((7 - i) << 2));
-       }
-}
-
-void
-panic_handler(unsigned long panicPC, unsigned long panicSSR,
-             unsigned long panicEXPEVT)
-{
-       while (1) {
-               /* This piece of code displays the PC on the LED display */
-               show_value(panicPC);
-               poor_mans_delay();
-               show_value(panicSSR);
-               poor_mans_delay();
-               show_value(panicEXPEVT);
-               poor_mans_delay();
-       }
-}
diff --git a/arch/sh/boards/mach-cayman/setup.c b/arch/sh/boards/mach-cayman/setup.c
deleted file mode 100644 (file)
index 8ef76e2..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * arch/sh/mach-cayman/setup.c
- *
- * SH5 Cayman support
- *
- * Copyright (C) 2002  David J. Mckay & Benedict Gaster
- * Copyright (C) 2003 - 2007  Paul Mundt
- */
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <cpu/irq.h>
-
-/*
- * Platform Dependent Interrupt Priorities.
- */
-
-/* Using defaults defined in irq.h */
-#define        RES NO_PRIORITY         /* Disabled */
-#define IR0 IRL0_PRIORITY      /* IRLs */
-#define IR1 IRL1_PRIORITY
-#define IR2 IRL2_PRIORITY
-#define IR3 IRL3_PRIORITY
-#define PCA INTA_PRIORITY      /* PCI Ints */
-#define PCB INTB_PRIORITY
-#define PCC INTC_PRIORITY
-#define PCD INTD_PRIORITY
-#define SER TOP_PRIORITY
-#define ERR TOP_PRIORITY
-#define PW0 TOP_PRIORITY
-#define PW1 TOP_PRIORITY
-#define PW2 TOP_PRIORITY
-#define PW3 TOP_PRIORITY
-#define DM0 NO_PRIORITY                /* DMA Ints */
-#define DM1 NO_PRIORITY
-#define DM2 NO_PRIORITY
-#define DM3 NO_PRIORITY
-#define DAE NO_PRIORITY
-#define TU0 TIMER_PRIORITY     /* TMU Ints */
-#define TU1 NO_PRIORITY
-#define TU2 NO_PRIORITY
-#define TI2 NO_PRIORITY
-#define ATI NO_PRIORITY                /* RTC Ints */
-#define PRI NO_PRIORITY
-#define CUI RTC_PRIORITY
-#define ERI SCIF_PRIORITY      /* SCIF Ints */
-#define RXI SCIF_PRIORITY
-#define BRI SCIF_PRIORITY
-#define TXI SCIF_PRIORITY
-#define ITI TOP_PRIORITY       /* WDT Ints */
-
-/* Setup for the SMSC FDC37C935 */
-#define SMSC_SUPERIO_BASE      0x04000000
-#define SMSC_CONFIG_PORT_ADDR  0x3f0
-#define SMSC_INDEX_PORT_ADDR   SMSC_CONFIG_PORT_ADDR
-#define SMSC_DATA_PORT_ADDR    0x3f1
-
-#define SMSC_ENTER_CONFIG_KEY  0x55
-#define SMSC_EXIT_CONFIG_KEY   0xaa
-
-#define SMCS_LOGICAL_DEV_INDEX 0x07
-#define SMSC_DEVICE_ID_INDEX   0x20
-#define SMSC_DEVICE_REV_INDEX  0x21
-#define SMSC_ACTIVATE_INDEX    0x30
-#define SMSC_PRIMARY_BASE_INDEX  0x60
-#define SMSC_SECONDARY_BASE_INDEX 0x62
-#define SMSC_PRIMARY_INT_INDEX 0x70
-#define SMSC_SECONDARY_INT_INDEX 0x72
-
-#define SMSC_IDE1_DEVICE       1
-#define SMSC_KEYBOARD_DEVICE   7
-#define SMSC_CONFIG_REGISTERS  8
-
-#define SMSC_SUPERIO_READ_INDEXED(index) ({ \
-       outb((index), SMSC_INDEX_PORT_ADDR); \
-       inb(SMSC_DATA_PORT_ADDR); })
-#define SMSC_SUPERIO_WRITE_INDEXED(val, index) ({ \
-       outb((index), SMSC_INDEX_PORT_ADDR); \
-       outb((val),   SMSC_DATA_PORT_ADDR); })
-
-#define IDE1_PRIMARY_BASE      0x01f0
-#define IDE1_SECONDARY_BASE    0x03f6
-
-unsigned long smsc_superio_virt;
-
-int platform_int_priority[NR_INTC_IRQS] = {
-       IR0, IR1, IR2, IR3, PCA, PCB, PCC, PCD, /* IRQ  0- 7 */
-       RES, RES, RES, RES, SER, ERR, PW3, PW2, /* IRQ  8-15 */
-       PW1, PW0, DM0, DM1, DM2, DM3, DAE, RES, /* IRQ 16-23 */
-       RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 24-31 */
-       TU0, TU1, TU2, TI2, ATI, PRI, CUI, ERI, /* IRQ 32-39 */
-       RXI, BRI, TXI, RES, RES, RES, RES, RES, /* IRQ 40-47 */
-       RES, RES, RES, RES, RES, RES, RES, RES, /* IRQ 48-55 */
-       RES, RES, RES, RES, RES, RES, RES, ITI, /* IRQ 56-63 */
-};
-
-static int __init smsc_superio_setup(void)
-{
-       unsigned char devid, devrev;
-
-       smsc_superio_virt = (unsigned long)ioremap(SMSC_SUPERIO_BASE, 1024);
-       if (!smsc_superio_virt) {
-               panic("Unable to remap SMSC SuperIO\n");
-       }
-
-       /* Initially the chip is in run state */
-       /* Put it into configuration state */
-       outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
-       outb(SMSC_ENTER_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
-
-       /* Read device ID info */
-       devid = SMSC_SUPERIO_READ_INDEXED(SMSC_DEVICE_ID_INDEX);
-       devrev = SMSC_SUPERIO_READ_INDEXED(SMSC_DEVICE_REV_INDEX);
-       printk("SMSC SuperIO devid %02x rev %02x\n", devid, devrev);
-
-       /* Select the keyboard device */
-       SMSC_SUPERIO_WRITE_INDEXED(SMSC_KEYBOARD_DEVICE, SMCS_LOGICAL_DEV_INDEX);
-
-       /* enable it */
-       SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
-
-       /* Select the interrupts */
-       /* On a PC keyboard is IRQ1, mouse is IRQ12 */
-       SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_PRIMARY_INT_INDEX);
-       SMSC_SUPERIO_WRITE_INDEXED(12, SMSC_SECONDARY_INT_INDEX);
-
-       /*
-        * Only IDE1 exists on the Cayman
-        */
-
-       /* Power it on */
-       SMSC_SUPERIO_WRITE_INDEXED(1 << SMSC_IDE1_DEVICE, 0x22);
-
-       SMSC_SUPERIO_WRITE_INDEXED(SMSC_IDE1_DEVICE, SMCS_LOGICAL_DEV_INDEX);
-       SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_ACTIVATE_INDEX);
-
-       SMSC_SUPERIO_WRITE_INDEXED(IDE1_PRIMARY_BASE >> 8,
-                                  SMSC_PRIMARY_BASE_INDEX + 0);
-       SMSC_SUPERIO_WRITE_INDEXED(IDE1_PRIMARY_BASE & 0xff,
-                                  SMSC_PRIMARY_BASE_INDEX + 1);
-
-       SMSC_SUPERIO_WRITE_INDEXED(IDE1_SECONDARY_BASE >> 8,
-                                  SMSC_SECONDARY_BASE_INDEX + 0);
-       SMSC_SUPERIO_WRITE_INDEXED(IDE1_SECONDARY_BASE & 0xff,
-                                  SMSC_SECONDARY_BASE_INDEX + 1);
-
-       SMSC_SUPERIO_WRITE_INDEXED(14, SMSC_PRIMARY_INT_INDEX);
-
-       SMSC_SUPERIO_WRITE_INDEXED(SMSC_CONFIG_REGISTERS,
-                                  SMCS_LOGICAL_DEV_INDEX);
-
-       SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc2); /* GP42 = nIDE1_OE */
-       SMSC_SUPERIO_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
-       SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
-       SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
-
-       /* Exit the configuration state */
-       outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
-
-       return 0;
-}
-device_initcall(smsc_superio_setup);
-
-static void __iomem *cayman_ioport_map(unsigned long port, unsigned int len)
-{
-       if (port < 0x400) {
-               extern unsigned long smsc_superio_virt;
-               return (void __iomem *)((port << 2) | smsc_superio_virt);
-       }
-
-       return (void __iomem *)port;
-}
-
-extern void init_cayman_irq(void);
-
-static struct sh_machine_vector mv_cayman __initmv = {
-       .mv_name                = "Hitachi Cayman",
-       .mv_ioport_map          = cayman_ioport_map,
-       .mv_init_irq            = init_cayman_irq,
-};
index 16b4d8b..2c44b94 100644 (file)
@@ -82,6 +82,9 @@ device_initcall(landisk_devices_setup);
 
 static void __init landisk_setup(char **cmdline_p)
 {
+       /* I/O port identity mapping */
+       __set_io_port_base(0);
+
        /* LED ON */
        __raw_writeb(__raw_readb(PA_LED) | 0x03, PA_LED);
 
diff --git a/arch/sh/configs/cayman_defconfig b/arch/sh/configs/cayman_defconfig
deleted file mode 100644 (file)
index 911437c..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-CONFIG_POSIX_MQUEUE=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_FORCE_MAX_ZONEORDER=11
-CONFIG_MEMORY_START=0x80000000
-CONFIG_MEMORY_SIZE=0x00400000
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_CACHE_OFF=y
-CONFIG_SH_PCLK_FREQ=50000000
-CONFIG_HEARTBEAT=y
-CONFIG_PREEMPT=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-# CONFIG_IPV6 is not set
-# CONFIG_FW_LOADER is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=m
-CONFIG_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_SH_MOBILE_LCDC=m
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x16=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-# CONFIG_LOGO_SUPERH_MONO is not set
-# CONFIG_LOGO_SUPERH_VGA16 is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_MINIX_FS=y
-CONFIG_ROMFS_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_SCHEDSTATS=y
-CONFIG_FRAME_POINTER=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
index ae067e0..6a82c7b 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_MODULES=y
index a5b865a..9a988c3 100644 (file)
@@ -5,7 +5,6 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_NAMESPACES=y
 CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
index a92db66..70e6605 100644 (file)
@@ -3,7 +3,6 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_CPU_SUBTYPE_SH7709=y
index 567af75..ba6ec04 100644 (file)
@@ -1,6 +1,5 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
index 10f6d37..05e4ac6 100644 (file)
@@ -1,6 +1,5 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
index ed84d13..c65667d 100644 (file)
@@ -2,7 +2,6 @@ CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_CPU_SUBTYPE_SH4_202=y
index 37e9521..a24cf8c 100644 (file)
@@ -4,7 +4,6 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
index c97ec60..e922659 100644 (file)
@@ -3,7 +3,6 @@ CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 CONFIG_SLAB=y
index 55fce65..5978866 100644 (file)
@@ -7,7 +7,6 @@ CONFIG_RCU_TRACE=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
index 6a3cfe0..fc9c221 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
index 2b3d7d2..ff3fd67 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
index 21a43f1..ff5bb44 100644 (file)
@@ -18,7 +18,6 @@ CONFIG_USER_NS=y
 CONFIG_PID_NS=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_ELF_CORE is not set
 # CONFIG_COMPAT_BRK is not set
index 4e794e7..5d6c193 100644 (file)
@@ -2,7 +2,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
index 3264415..71a672c 100644 (file)
@@ -1,7 +1,6 @@
 # CONFIG_LOCALVERSION_AUTO is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_ELF_CORE is not set
index 4496b94..ed00a6e 100644 (file)
@@ -2,7 +2,6 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_SLAB=y
index b23f675..3f1c137 100644 (file)
@@ -5,7 +5,6 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
index 1623436..4a02406 100644 (file)
@@ -3,7 +3,6 @@ CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
index 360592d..8422599 100644 (file)
@@ -1,7 +1,6 @@
 # CONFIG_SWAP is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_SLAB=y
 # CONFIG_BLK_DEV_BSG is not set
index 87db9a8..f0073ed 100644 (file)
@@ -3,7 +3,6 @@ CONFIG_POSIX_MQUEUE=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=m
index 0842691..0d81477 100644 (file)
@@ -2,7 +2,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_FUTEX is not set
 # CONFIG_EPOLL is not set
 # CONFIG_SHMEM is not set
index d0933a9..a2700ab 100644 (file)
@@ -8,7 +8,6 @@ CONFIG_TASK_XACCT=y
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS_ALL=y
 CONFIG_SLAB=y
 CONFIG_MODULES=y
index d0a0aa7..26c5fd0 100644 (file)
@@ -5,7 +5,6 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_NAMESPACES=y
 CONFIG_UTS_NS=y
 CONFIG_IPC_NS=y
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
index a27b129..c0b6f40 100644 (file)
@@ -1,7 +1,6 @@
 # CONFIG_SWAP is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_UID16 is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_KALLSYMS is not set
 # CONFIG_HOTPLUG is not set
 # CONFIG_BUG is not set
index 4ec961a..ba887f1 100644 (file)
@@ -6,7 +6,6 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=16
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
index a5c1e90..d313fd3 100644 (file)
@@ -25,4 +25,3 @@ obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o
 obj-$(CONFIG_SH_TITAN)                 += fixups-titan.o
 obj-$(CONFIG_SH_LANDISK)               += fixups-landisk.o
 obj-$(CONFIG_SH_LBOX_RE2)              += fixups-rts7751r2d.o
-obj-$(CONFIG_SH_CAYMAN)                        += fixups-cayman.o
index fe163ec..2fd2b77 100644 (file)
@@ -54,7 +54,7 @@ int __init pci_is_66mhz_capable(struct pci_channel *hose,
        int cap66 = -1;
        u16 stat;
 
-       printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n");
+       pr_info("PCI: Checking 66MHz capabilities...\n");
 
        for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
                if (PCI_FUNC(pci_devfn))
@@ -134,7 +134,7 @@ unsigned int pcibios_handle_status_errors(unsigned long addr,
                pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT |
                                      PCI_STATUS_SIG_TARGET_ABORT |
                                      PCI_STATUS_REC_MASTER_ABORT, 1);
-               printk("\n");
+               pr_cont("\n");
 
                cmd |= PCI_STATUS_REC_TARGET_ABORT;
        }
@@ -143,7 +143,7 @@ unsigned int pcibios_handle_status_errors(unsigned long addr,
                printk(KERN_DEBUG "PCI: parity error detected: ");
                pcibios_report_status(PCI_STATUS_PARITY |
                                      PCI_STATUS_DETECTED_PARITY, 1);
-               printk("\n");
+               pr_cont("\n");
 
                cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY;
 
diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c
deleted file mode 100644 (file)
index c797bfb..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <cpu/irq.h>
-#include "pci-sh5.h"
-
-int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-       int result = -1;
-
-       /* The complication here is that the PCI IRQ lines from the Cayman's 2
-          5V slots get into the CPU via a different path from the IRQ lines
-          from the 3 3.3V slots.  Thus, we have to detect whether the card's
-          interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
-          at the point where we cross from 5V to 3.3V is not the normal case.
-
-          The added complication is that we don't know that the 5V slots are
-          always bus 2, because a card containing a PCI-PCI bridge may be
-          plugged into a 3.3V slot, and this changes the bus numbering.
-
-          Also, the Cayman has an intermediate PCI bus that goes a custom
-          expansion board header (and to the secondary bridge).  This bus has
-          never been used in practice.
-
-          The 1ary onboard PCI-PCI bridge is device 3 on bus 0
-          The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of
-          the 1ary bridge.
-          */
-
-       struct slot_pin {
-               int slot;
-               int pin;
-       } path[4];
-       int i=0;
-
-       while (dev->bus->number > 0) {
-
-               slot = path[i].slot = PCI_SLOT(dev->devfn);
-               pin = path[i].pin = pci_swizzle_interrupt_pin(dev, pin);
-               dev = dev->bus->self;
-               i++;
-               if (i > 3) panic("PCI path to root bus too long!\n");
-       }
-
-       slot = PCI_SLOT(dev->devfn);
-       /* This is the slot on bus 0 through which the device is eventually
-          reachable. */
-
-       /* Now work back up. */
-       if ((slot < 3) || (i == 0)) {
-               /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
-                  swizzle now. */
-               result = IRQ_INTA + pci_swizzle_interrupt_pin(dev, pin) - 1;
-       } else {
-               i--;
-               slot = path[i].slot;
-               pin  = path[i].pin;
-               if (slot > 0) {
-                       panic("PCI expansion bus device found - not handled!\n");
-               } else {
-                       if (i > 0) {
-                               /* 5V slots */
-                               i--;
-                               slot = path[i].slot;
-                               pin  = path[i].pin;
-                               /* 'pin' was swizzled earlier wrt slot, don't do it again. */
-                               result = IRQ_P2INTA + (pin - 1);
-                       } else {
-                               /* IRQ for 2ary PCI-PCI bridge : unused */
-                               result = -1;
-                       }
-               }
-       }
-
-       return result;
-}
index 287b3a6..9a624a6 100644 (file)
@@ -148,7 +148,7 @@ static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id)
 
        printk(KERN_DEBUG "PCI: system error received: ");
        pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
-       printk("\n");
+       pr_cont("\n");
 
        /* Deassert SERR */
        __raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM);
@@ -179,7 +179,7 @@ static int __init sh7780_pci_setup_irqs(struct pci_channel *hose)
        ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, 0,
                          "PCI SERR interrupt", hose);
        if (unlikely(ret)) {
-               printk(KERN_ERR "PCI: Failed hooking SERR IRQ\n");
+               pr_err("PCI: Failed hooking SERR IRQ\n");
                return ret;
        }
 
@@ -250,7 +250,7 @@ static int __init sh7780_pci_init(void)
        const char *type;
        int ret, i;
 
-       printk(KERN_NOTICE "PCI: Starting initialization.\n");
+       pr_notice("PCI: Starting initialization.\n");
 
        chan->reg_base = 0xfe040000;
 
@@ -270,7 +270,7 @@ static int __init sh7780_pci_init(void)
 
        id = __raw_readw(chan->reg_base + PCI_VENDOR_ID);
        if (id != PCI_VENDOR_ID_RENESAS) {
-               printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id);
+               pr_err("PCI: Unknown vendor ID 0x%04x.\n", id);
                return -ENODEV;
        }
 
@@ -281,14 +281,13 @@ static int __init sh7780_pci_init(void)
               (id == PCI_DEVICE_ID_RENESAS_SH7785) ? "SH7785" :
                                          NULL;
        if (unlikely(!type)) {
-               printk(KERN_ERR "PCI: Found an unsupported Renesas host "
-                      "controller, device id 0x%04x.\n", id);
+               pr_err("PCI: Found an unsupported Renesas host controller, device id 0x%04x.\n",
+                      id);
                return -EINVAL;
        }
 
-       printk(KERN_NOTICE "PCI: Found a Renesas %s host "
-              "controller, revision %d.\n", type,
-              __raw_readb(chan->reg_base + PCI_REVISION_ID));
+       pr_notice("PCI: Found a Renesas %s host controller, revision %d.\n",
+                 type, __raw_readb(chan->reg_base + PCI_REVISION_ID));
 
        /*
         * Now throw it in to register initialization mode and
@@ -395,9 +394,9 @@ static int __init sh7780_pci_init(void)
 
        sh7780_pci66_init(chan);
 
-       printk(KERN_NOTICE "PCI: Running at %dMHz.\n",
-              (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ) ?
-              66 : 33);
+       pr_notice("PCI: Running at %dMHz.\n",
+                 (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ)
+                 ? 66 : 33);
 
        return 0;
 
index c7784e1..6ab0b73 100644 (file)
@@ -120,8 +120,7 @@ int register_pci_controller(struct pci_channel *hose)
         * Do not panic here but later - this might happen before console init.
         */
        if (!hose->io_map_base) {
-               printk(KERN_WARNING
-                      "registering PCI controller with io_map_base unset\n");
+               pr_warn("registering PCI controller with io_map_base unset\n");
        }
 
        /*
@@ -145,7 +144,7 @@ out:
        for (--i; i >= 0; i--)
                release_resource(&hose->resources[i]);
 
-       printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n");
+       pr_warn("Skipping PCI bus scan due to resource conflict\n");
        return -1;
 }
 
@@ -213,8 +212,8 @@ pcibios_bus_report_status_early(struct pci_channel *hose,
                                        pci_devfn, PCI_STATUS,
                                        status & status_mask);
                if (warn)
-                       printk("(%02x:%02x: %04X) ", current_bus,
-                              pci_devfn, status);
+                       pr_cont("(%02x:%02x: %04X) ", current_bus, pci_devfn,
+                               status);
        }
 }
 
@@ -249,7 +248,7 @@ pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask,
                pci_write_config_word(dev, PCI_STATUS, status & status_mask);
 
                if (warn)
-                       printk("(%s: %04X) ", pci_name(dev), status);
+                       pr_cont("(%s: %04X) ", pci_name(dev), status);
        }
 
        list_for_each_entry(dev, &bus->devices, bus_list)
index 99ec668..feccfe6 100644 (file)
@@ -1,7 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef __ASM_ADC_H
 #define __ASM_ADC_H
-#ifdef __KERNEL__
 /*
  * Copyright (C) 2004  Andriy Skulysh
  */
@@ -10,5 +9,4 @@
 
 int adc_single(unsigned int channel);
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_ADC_H */
index 34bfbcd..468fba3 100644 (file)
@@ -7,8 +7,6 @@
 #ifndef __ASM_SH_ADDRSPACE_H
 #define __ASM_SH_ADDRSPACE_H
 
-#ifdef __KERNEL__
-
 #include <cpu/addrspace.h>
 
 /* If this CPU supports segmentation, hook up the helpers */
@@ -62,5 +60,4 @@
 #define P3_ADDR_MAX            P4SEG
 #endif
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_ADDRSPACE_H */
index 445dd14..450b585 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __ASM_SH_BITOPS_H
 #define __ASM_SH_BITOPS_H
 
-#ifdef __KERNEL__
-
 #ifndef _LINUX_BITOPS_H
 #error only <linux/bitops.h> can be included directly
 #endif
@@ -71,6 +69,4 @@ static inline unsigned long __ffs(unsigned long word)
 #include <asm-generic/bitops/__fls.h>
 #include <asm-generic/bitops/fls64.h>
 
-#endif /* __KERNEL__ */
-
 #endif /* __ASM_SH_BITOPS_H */
index 2408ac4..a293343 100644 (file)
@@ -8,7 +8,6 @@
  */
 #ifndef __ASM_SH_CACHE_H
 #define __ASM_SH_CACHE_H
-#ifdef __KERNEL__
 
 #include <linux/init.h>
 #include <cpu/cache.h>
@@ -44,5 +43,4 @@ struct cache_info {
        unsigned long flags;
 };
 #endif /* __ASSEMBLY__ */
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_CACHE_H */
index fe74000..4486a86 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __ASM_SH_CACHEFLUSH_H
 #define __ASM_SH_CACHEFLUSH_H
 
-#ifdef __KERNEL__
-
 #include <linux/mm.h>
 
 /*
@@ -109,5 +107,4 @@ static inline void *sh_cacheop_vaddr(void *vaddr)
        return vaddr;
 }
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_CACHEFLUSH_H */
index 4d5a21a..17d23ae 100644 (file)
@@ -6,7 +6,6 @@
  */
 #ifndef __ASM_SH_DMA_H
 #define __ASM_SH_DMA_H
-#ifdef __KERNEL__
 
 #include <linux/spinlock.h>
 #include <linux/wait.h>
@@ -144,5 +143,4 @@ extern int isa_dma_bridge_buggy;
 #define isa_dma_bridge_buggy   (0)
 #endif
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_DMA_H */
index 7661fb5..2862d6d 100644 (file)
@@ -90,7 +90,6 @@ typedef struct user_fpu_struct elf_fpregset_t;
 #endif
 #define ELF_ARCH       EM_SH
 
-#ifdef __KERNEL__
 /*
  * This is used to ensure we don't load something for the wrong architecture.
  */
@@ -209,5 +208,4 @@ do {                                                                \
        NEW_AUX_ENT(AT_L2_CACHESHAPE, l2_cache_shape);          \
 } while (0)
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_ELF_H */
index 18133bf..87c2362 100644 (file)
@@ -6,9 +6,7 @@
  */
 #ifndef __ASM_SH_FREQ_H
 #define __ASM_SH_FREQ_H
-#ifdef __KERNEL__
 
 #include <cpu/freq.h>
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_FREQ_H */
index b39cda0..b70f3fc 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __ASM_SH_FUTEX_H
 #define __ASM_SH_FUTEX_H
 
-#ifdef __KERNEL__
-
 #include <linux/futex.h>
 #include <linux/uaccess.h>
 #include <asm/errno.h>
@@ -71,5 +69,4 @@ static inline int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval,
        return ret;
 }
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_FUTEX_H */
index ec587b5..6d5c646 100644 (file)
 #include <linux/pgtable.h>
 #include <asm-generic/iomap.h>
 
-#ifdef __KERNEL__
 #define __IO_PREFIX     generic
 #include <asm/io_generic.h>
-#include <asm/io_trapped.h>
 #include <asm-generic/pci_iomap.h>
 #include <mach/mangle-port.h>
 
@@ -244,125 +242,38 @@ unsigned long long poke_real_address_q(unsigned long long addr,
 #define phys_to_virt(address)  (__va(address))
 #endif
 
-/*
- * On 32-bit SH, we traditionally have the whole physical address space
- * mapped at all times (as MIPS does), so "ioremap()" and "iounmap()" do
- * not need to do anything but place the address in the proper segment.
- * This is true for P1 and P2 addresses, as well as some P3 ones.
- * However, most of the P3 addresses and newer cores using extended
- * addressing need to map through page tables, so the ioremap()
- * implementation becomes a bit more complicated.
- *
- * See arch/sh/mm/ioremap.c for additional notes on this.
- *
- * We cheat a bit and always return uncachable areas until we've fixed
- * the drivers to handle caching properly.
- *
- * On the SH-5 the concept of segmentation in the 1:1 PXSEG sense simply
- * doesn't exist, so everything must go through page tables.
- */
 #ifdef CONFIG_MMU
+void iounmap(void __iomem *addr);
 void __iomem *__ioremap_caller(phys_addr_t offset, unsigned long size,
                               pgprot_t prot, void *caller);
-void iounmap(void __iomem *addr);
-
-static inline void __iomem *
-__ioremap(phys_addr_t offset, unsigned long size, pgprot_t prot)
-{
-       return __ioremap_caller(offset, size, prot, __builtin_return_address(0));
-}
-
-static inline void __iomem *
-__ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
-{
-#ifdef CONFIG_29BIT
-       phys_addr_t last_addr = offset + size - 1;
-
-       /*
-        * For P1 and P2 space this is trivial, as everything is already
-        * mapped. Uncached access for P1 addresses are done through P2.
-        * In the P3 case or for addresses outside of the 29-bit space,
-        * mapping must be done by the PMB or by using page tables.
-        */
-       if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
-               u64 flags = pgprot_val(prot);
-
-               /*
-                * Anything using the legacy PTEA space attributes needs
-                * to be kicked down to page table mappings.
-                */
-               if (unlikely(flags & _PAGE_PCC_MASK))
-                       return NULL;
-               if (unlikely(flags & _PAGE_CACHABLE))
-                       return (void __iomem *)P1SEGADDR(offset);
-
-               return (void __iomem *)P2SEGADDR(offset);
-       }
-
-       /* P4 above the store queues are always mapped. */
-       if (unlikely(offset >= P3_ADDR_MAX))
-               return (void __iomem *)P4SEGADDR(offset);
-#endif
-
-       return NULL;
-}
-
-static inline void __iomem *
-__ioremap_mode(phys_addr_t offset, unsigned long size, pgprot_t prot)
-{
-       void __iomem *ret;
-
-       ret = __ioremap_trapped(offset, size);
-       if (ret)
-               return ret;
-
-       ret = __ioremap_29bit(offset, size, prot);
-       if (ret)
-               return ret;
-
-       return __ioremap(offset, size, prot);
-}
-#else
-#define __ioremap(offset, size, prot)          ((void __iomem *)(offset))
-#define __ioremap_mode(offset, size, prot)     ((void __iomem *)(offset))
-static inline void iounmap(void __iomem *addr) {}
-#endif /* CONFIG_MMU */
 
 static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)
 {
-       return __ioremap_mode(offset, size, PAGE_KERNEL_NOCACHE);
+       return __ioremap_caller(offset, size, PAGE_KERNEL_NOCACHE,
+                       __builtin_return_address(0));
 }
 
 static inline void __iomem *
 ioremap_cache(phys_addr_t offset, unsigned long size)
 {
-       return __ioremap_mode(offset, size, PAGE_KERNEL);
+       return __ioremap_caller(offset, size, PAGE_KERNEL,
+                       __builtin_return_address(0));
 }
 #define ioremap_cache ioremap_cache
 
 #ifdef CONFIG_HAVE_IOREMAP_PROT
-static inline void __iomem *
-ioremap_prot(phys_addr_t offset, unsigned long size, unsigned long flags)
+static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
+               unsigned long flags)
 {
-       return __ioremap_mode(offset, size, __pgprot(flags));
+       return __ioremap_caller(offset, size, __pgprot(flags),
+                       __builtin_return_address(0));
 }
-#endif
+#endif /* CONFIG_HAVE_IOREMAP_PROT */
 
-#ifdef CONFIG_IOREMAP_FIXED
-extern void __iomem *ioremap_fixed(phys_addr_t, unsigned long, pgprot_t);
-extern int iounmap_fixed(void __iomem *);
-extern void ioremap_fixed_init(void);
-#else
-static inline void __iomem *
-ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
-{
-       BUG();
-       return NULL;
-}
-
-static inline void ioremap_fixed_init(void) { }
-static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
-#endif
+#else /* CONFIG_MMU */
+#define iounmap(addr)          do { } while (0)
+#define ioremap(offset, size)  ((void __iomem *)(unsigned long)(offset))
+#endif /* CONFIG_MMU */
 
 #define ioremap_uc     ioremap
 
@@ -381,6 +292,4 @@ static inline int iounmap_fixed(void __iomem *addr) { return -EINVAL; }
 int valid_phys_addr_range(phys_addr_t addr, size_t size);
 int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
 
-#endif /* __KERNEL__ */
-
 #endif /* __ASM_SH_IO_H */
index 9605453..de8693f 100644 (file)
@@ -12,8 +12,7 @@ enum die_val {
 };
 
 /* arch/sh/kernel/dumpstack.c */
-extern void printk_address(unsigned long address, int reliable,
-                          const char *loglvl);
+extern void printk_address(unsigned long address, int reliable);
 extern void dump_mem(const char *str, const char *loglvl,
                     unsigned long bottom, unsigned long top);
 
index 48e67d5..f664e51 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef __ASM_SH_MMU_CONTEXT_H
 #define __ASM_SH_MMU_CONTEXT_H
 
-#ifdef __KERNEL__
 #include <cpu/mmu_context.h>
 #include <asm/tlbflush.h>
 #include <linux/uaccess.h>
@@ -177,5 +176,4 @@ static inline void disable_mmu(void)
 #define disable_mmu()  do { } while (0)
 #endif
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_MMU_CONTEXT_H */
index cbaee1d..6552a08 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __ASM_SH_MMZONE_H
 #define __ASM_SH_MMZONE_H
 
-#ifdef __KERNEL__
-
 #ifdef CONFIG_NEED_MULTIPLE_NODES
 #include <linux/numa.h>
 
@@ -44,5 +42,4 @@ void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
 /* arch/sh/mm/init.c */
 void __init allocate_pgdat(unsigned int nid);
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_MMZONE_H */
index 10a36b1..ad22e88 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __ASM_SH_PCI_H
 #define __ASM_SH_PCI_H
 
-#ifdef __KERNEL__
-
 /* Can be used to override the logic in pci_scan_bus for skipping
    already-configured bus numbers - to be used for buggy BIOSes
    or architectures with incomplete PCI setup by the loader */
@@ -96,6 +94,4 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
        return channel ? 15 : 14;
 }
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_PCI_H */
-
index d444094..aa92cc9 100644 (file)
@@ -8,7 +8,6 @@
 
 #ifndef __ASM_SH_PROCESSOR_32_H
 #define __ASM_SH_PROCESSOR_32_H
-#ifdef __KERNEL__
 
 #include <linux/compiler.h>
 #include <linux/linkage.h>
@@ -203,5 +202,4 @@ static inline void prefetchw(const void *x)
 }
 #endif
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_PROCESSOR_32_H */
index f054c30..891f2f8 100644 (file)
@@ -112,8 +112,8 @@ typedef struct uart_reg {
 #define FCR_RFRES      0x0200  /* Receiver FIFO reset */
 #define FCR_TFRES      0x0400  /* Transmitter FIFO reset */
 #define FCR_DMA                0x0800  /* DMA mode select */
-#define FCR_RTL                0x4000  /* Receiver triger (LSB) */
-#define FCR_RTM                0x8000  /* Receiver triger (MSB) */
+#define FCR_RTL                0x4000  /* Receiver trigger (LSB) */
+#define FCR_RTM                0x8000  /* Receiver trigger (MSB) */
 
 /* Line Control Register */
 
index 084706b..4703cbe 100644 (file)
@@ -2,7 +2,6 @@
 #ifndef __ASM_SH_SPARSEMEM_H
 #define __ASM_SH_SPARSEMEM_H
 
-#ifdef __KERNEL__
 /*
  * SECTION_SIZE_BITS           2^N: how big each section will be
  * MAX_PHYSMEM_BITS            2^N: how much physical address space we have
@@ -10,6 +9,4 @@
 #define SECTION_SIZE_BITS      26
 #define MAX_PHYSMEM_BITS       32
 
-#endif
-
 #endif /* __ASM_SH_SPARSEMEM_H */
index 50c173c..4f98cdc 100644 (file)
@@ -12,8 +12,6 @@
 
 struct stacktrace_ops {
        void (*address)(void *data, unsigned long address, int reliable);
-       /* On negative return stop dumping */
-       int (*stack)(void *data, char *name);
 };
 
 void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
index 3558b1d..a276b19 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __ASM_SH_STRING_H
 #define __ASM_SH_STRING_H
 
-#ifdef __KERNEL__
-
 /*
  * Copyright (C) 1999 Niibe Yutaka
  * But consider these trivial functions to be public domain.
@@ -28,32 +26,6 @@ static inline char *strcpy(char *__dest, const char *__src)
        return __xdest;
 }
 
-#define __HAVE_ARCH_STRNCPY
-static inline char *strncpy(char *__dest, const char *__src, size_t __n)
-{
-       register char *__xdest = __dest;
-       unsigned long __dummy;
-
-       if (__n == 0)
-               return __xdest;
-
-       __asm__ __volatile__(
-               "1:\n"
-               "mov.b  @%1+, %2\n\t"
-               "mov.b  %2, @%0\n\t"
-               "cmp/eq #0, %2\n\t"
-               "bt/s   2f\n\t"
-               " cmp/eq        %5,%1\n\t"
-               "bf/s   1b\n\t"
-               " add   #1, %0\n"
-               "2:"
-               : "=r" (__dest), "=r" (__src), "=&z" (__dummy)
-               : "0" (__dest), "1" (__src), "r" (__src+__n)
-               : "memory", "t");
-
-       return __xdest;
-}
-
 #define __HAVE_ARCH_STRCMP
 static inline int strcmp(const char *__cs, const char *__ct)
 {
@@ -127,6 +99,4 @@ extern void *memchr(const void *__s, int __c, size_t __n);
 #define __HAVE_ARCH_STRLEN
 extern size_t strlen(const char *);
 
-#endif /* __KERNEL__ */
-
 #endif /* __ASM_SH_STRING_H */
index 0b5b8e7..cb51a75 100644 (file)
@@ -40,10 +40,7 @@ static inline void syscall_set_return_value(struct task_struct *task,
                                            struct pt_regs *regs,
                                            int error, long val)
 {
-       if (error)
-               regs->regs[0] = -error;
-       else
-               regs->regs[0] = val;
+       regs->regs[0] = (long) error ?: val;
 }
 
 static inline void syscall_get_arguments(struct task_struct *task,
index 9f9faf6..5c555b8 100644 (file)
@@ -2,8 +2,6 @@
 #ifndef __ASM_SH_SYSCALLS_32_H
 #define __ASM_SH_SYSCALLS_32_H
 
-#ifdef __KERNEL__
-
 #include <linux/compiler.h>
 #include <linux/linkage.h>
 #include <linux/types.h>
@@ -26,5 +24,4 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
 asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
                                 unsigned long thread_info_flags);
 
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_SYSCALLS_32_H */
index 6404be6..243ea51 100644 (file)
@@ -10,8 +10,6 @@
  *  Copyright (C) 2002  David Howells (dhowells@redhat.com)
  *  - Incorporating suggestions made by Linus Torvalds and Dave Miller
  */
-#ifdef __KERNEL__
-
 #include <asm/page.h>
 
 /*
@@ -170,7 +168,4 @@ static inline unsigned int get_thread_fault_code(void)
 }
 
 #endif /* !__ASSEMBLY__ */
-
-#endif /* __KERNEL__ */
-
 #endif /* __ASM_SH_THREAD_INFO_H */
index 624cf55..5d7ddc0 100644 (file)
@@ -26,6 +26,9 @@ do {                                                          \
        case 4:                                                 \
                __get_user_asm(x, ptr, retval, "l");            \
                break;                                          \
+       case 8:                                                 \
+               __get_user_u64(x, ptr, retval);                 \
+               break;                                          \
        default:                                                \
                __get_user_unknown();                           \
                break;                                          \
@@ -66,6 +69,56 @@ do {                                                 \
 
 extern void __get_user_unknown(void);
 
+#if defined(CONFIG_CPU_LITTLE_ENDIAN)
+#define __get_user_u64(x, addr, err) \
+({ \
+__asm__ __volatile__( \
+       "1:\n\t" \
+       "mov.l  %2,%R1\n\t" \
+       "mov.l  %T2,%S1\n\t" \
+       "2:\n" \
+       ".section       .fixup,\"ax\"\n" \
+       "3:\n\t" \
+       "mov  #0,%R1\n\t"   \
+       "mov  #0,%S1\n\t"   \
+       "mov.l  4f, %0\n\t" \
+       "jmp    @%0\n\t" \
+       " mov   %3, %0\n\t" \
+       ".balign        4\n" \
+       "4:     .long   2b\n\t" \
+       ".previous\n" \
+       ".section       __ex_table,\"a\"\n\t" \
+       ".long  1b, 3b\n\t" \
+       ".long  1b + 2, 3b\n\t" \
+       ".previous" \
+       :"=&r" (err), "=&r" (x) \
+       :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); })
+#else
+#define __get_user_u64(x, addr, err) \
+({ \
+__asm__ __volatile__( \
+       "1:\n\t" \
+       "mov.l  %2,%S1\n\t" \
+       "mov.l  %T2,%R1\n\t" \
+       "2:\n" \
+       ".section       .fixup,\"ax\"\n" \
+       "3:\n\t" \
+       "mov  #0,%S1\n\t"   \
+       "mov  #0,%R1\n\t"   \
+       "mov.l  4f, %0\n\t" \
+       "jmp    @%0\n\t" \
+       " mov   %3, %0\n\t" \
+       ".balign        4\n" \
+       "4:     .long   2b\n\t" \
+       ".previous\n" \
+       ".section       __ex_table,\"a\"\n\t" \
+       ".long  1b, 3b\n\t" \
+       ".long  1b + 2, 3b\n\t" \
+       ".previous" \
+       :"=&r" (err), "=&r" (x) \
+       :"m" (__m(addr)), "i" (-EFAULT), "0" (err)); })
+#endif
+
 #define __put_user_size(x,ptr,size,retval)             \
 do {                                                   \
        retval = 0;                                     \
index cecd0fc..b9ca4c9 100644 (file)
@@ -8,7 +8,6 @@
  */
 #ifndef __ASM_SH_WATCHDOG_H
 #define __ASM_SH_WATCHDOG_H
-#ifdef __KERNEL__
 
 #include <linux/types.h>
 #include <linux/io.h>
@@ -157,5 +156,4 @@ static inline void sh_wdt_write_csr(__u8 val)
        __raw_writew((WTCSR_HIGH << 8) | (__u16)val, WTCSR);
 }
 #endif /* CONFIG_CPU_SUBTYPE_SH7785 || CONFIG_CPU_SUBTYPE_SH7780 */
-#endif /* __KERNEL__ */
 #endif /* __ASM_SH_WATCHDOG_H */
index b0f5574..aa0fbc9 100644 (file)
@@ -47,5 +47,3 @@ obj-$(CONFIG_DWARF_UNWINDER)  += dwarf.o
 obj-$(CONFIG_PERF_EVENTS)      += perf_event.o perf_callchain.o
 obj-$(CONFIG_DMA_NONCOHERENT)  += dma-coherent.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)               += hw_breakpoint.o
-
-ccflags-y := -Werror
index 8455437..08e1af6 100644 (file)
@@ -376,148 +376,148 @@ static void print_sh_insn(u32 memaddr, u16 insn)
                }
 
        ok:
-               printk("%-8s  ", op->name);
+               pr_cont("%-8s  ", op->name);
                lastsp = (op->arg[0] == A_END);
                disp_pc = 0;
                for (n = 0; n < 6 && op->arg[n] != A_END; n++) {
                        if (n && op->arg[1] != A_END)
-                               printk(", ");
+                               pr_cont(", ");
                        switch (op->arg[n]) {
                        case A_IMM:
-                               printk("#%d", (char)(imm));
+                               pr_cont("#%d", (char)(imm));
                                break;
                        case A_R0:
-                               printk("r0");
+                               pr_cont("r0");
                                break;
                        case A_REG_N:
-                               printk("r%d", rn);
+                               pr_cont("r%d", rn);
                                break;
                        case A_INC_N:
-                               printk("@r%d+", rn);
+                               pr_cont("@r%d+", rn);
                                break;
                        case A_DEC_N:
-                               printk("@-r%d", rn);
+                               pr_cont("@-r%d", rn);
                                break;
                        case A_IND_N:
-                               printk("@r%d", rn);
+                               pr_cont("@r%d", rn);
                                break;
                        case A_DISP_REG_N:
-                               printk("@(%d,r%d)", imm, rn);
+                               pr_cont("@(%d,r%d)", imm, rn);
                                break;
                        case A_REG_M:
-                               printk("r%d", rm);
+                               pr_cont("r%d", rm);
                                break;
                        case A_INC_M:
-                               printk("@r%d+", rm);
+                               pr_cont("@r%d+", rm);
                                break;
                        case A_DEC_M:
-                               printk("@-r%d", rm);
+                               pr_cont("@-r%d", rm);
                                break;
                        case A_IND_M:
-                               printk("@r%d", rm);
+                               pr_cont("@r%d", rm);
                                break;
                        case A_DISP_REG_M:
-                               printk("@(%d,r%d)", imm, rm);
+                               pr_cont("@(%d,r%d)", imm, rm);
                                break;
                        case A_REG_B:
-                               printk("r%d_bank", rb);
+                               pr_cont("r%d_bank", rb);
                                break;
                        case A_DISP_PC:
                                disp_pc = 1;
                                disp_pc_addr = imm + 4 + (memaddr & relmask);
-                               printk("%08x <%pS>", disp_pc_addr,
-                                      (void *)disp_pc_addr);
+                               pr_cont("%08x <%pS>", disp_pc_addr,
+                                       (void *)disp_pc_addr);
                                break;
                        case A_IND_R0_REG_N:
-                               printk("@(r0,r%d)", rn);
+                               pr_cont("@(r0,r%d)", rn);
                                break;
                        case A_IND_R0_REG_M:
-                               printk("@(r0,r%d)", rm);
+                               pr_cont("@(r0,r%d)", rm);
                                break;
                        case A_DISP_GBR:
-                               printk("@(%d,gbr)",imm);
+                               pr_cont("@(%d,gbr)", imm);
                                break;
                        case A_R0_GBR:
-                               printk("@(r0,gbr)");
+                               pr_cont("@(r0,gbr)");
                                break;
                        case A_BDISP12:
                        case A_BDISP8:
-                               printk("%08x", imm + memaddr);
+                               pr_cont("%08x", imm + memaddr);
                                break;
                        case A_SR:
-                               printk("sr");
+                               pr_cont("sr");
                                break;
                        case A_GBR:
-                               printk("gbr");
+                               pr_cont("gbr");
                                break;
                        case A_VBR:
-                               printk("vbr");
+                               pr_cont("vbr");
                                break;
                        case A_SSR:
-                               printk("ssr");
+                               pr_cont("ssr");
                                break;
                        case A_SPC:
-                               printk("spc");
+                               pr_cont("spc");
                                break;
                        case A_MACH:
-                               printk("mach");
+                               pr_cont("mach");
                                break;
                        case A_MACL:
-                               printk("macl");
+                               pr_cont("macl");
                                break;
                        case A_PR:
-                               printk("pr");
+                               pr_cont("pr");
                                break;
                        case A_SGR:
-                               printk("sgr");
+                               pr_cont("sgr");
                                break;
                        case A_DBR:
-                               printk("dbr");
+                               pr_cont("dbr");
                                break;
                        case FD_REG_N:
                        case F_REG_N:
-                               printk("fr%d", rn);
+                               pr_cont("fr%d", rn);
                                break;
                        case F_REG_M:
-                               printk("fr%d", rm);
+                               pr_cont("fr%d", rm);
                                break;
                        case DX_REG_N:
                                if (rn & 1) {
-                                       printk("xd%d", rn & ~1);
+                                       pr_cont("xd%d", rn & ~1);
                                        break;
                                }
                                /* else, fall through */
                        case D_REG_N:
-                               printk("dr%d", rn);
+                               pr_cont("dr%d", rn);
                                break;
                        case DX_REG_M:
                                if (rm & 1) {
-                                       printk("xd%d", rm & ~1);
+                                       pr_cont("xd%d", rm & ~1);
                                        break;
                                }
                                /* else, fall through */
                        case D_REG_M:
-                               printk("dr%d", rm);
+                               pr_cont("dr%d", rm);
                                break;
                        case FPSCR_M:
                        case FPSCR_N:
-                               printk("fpscr");
+                               pr_cont("fpscr");
                                break;
                        case FPUL_M:
                        case FPUL_N:
-                               printk("fpul");
+                               pr_cont("fpul");
                                break;
                        case F_FR0:
-                               printk("fr0");
+                               pr_cont("fr0");
                                break;
                        case V_REG_N:
-                               printk("fv%d", rn*4);
+                               pr_cont("fv%d", rn*4);
                                break;
                        case V_REG_M:
-                               printk("fv%d", rm*4);
+                               pr_cont("fv%d", rm*4);
                                break;
                        case XMTRX_M4:
-                               printk("xmtrx");
+                               pr_cont("xmtrx");
                                break;
                        default:
                                return;
@@ -532,7 +532,7 @@ static void print_sh_insn(u32 memaddr, u16 insn)
                        else
                                __get_user(val, (u32 *)disp_pc_addr);
 
-                       printk("  ! %08x <%pS>", val, (void *)val);
+                       pr_cont("  ! %08x <%pS>", val, (void *)val);
                }
 
                return;
@@ -541,7 +541,7 @@ static void print_sh_insn(u32 memaddr, u16 insn)
 
        }
 
-       printk(".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
+       pr_info(".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
 }
 
 void show_code(struct pt_regs *regs)
@@ -552,20 +552,21 @@ void show_code(struct pt_regs *regs)
        if (regs->pc & 0x1)
                return;
 
-       printk("Code:\n");
+       pr_info("Code:\n");
 
        for (i = -3 ; i < 6 ; i++) {
                unsigned short insn;
 
                if (__get_user(insn, pc + i)) {
-                       printk(" (Bad address in pc)\n");
+                       pr_err(" (Bad address in pc)\n");
                        break;
                }
 
-               printk("%s%08lx:  ", (i ? "  ": "->"), (unsigned long)(pc + i));
+               pr_info("%s%08lx:  ", (i ? "  " : "->"),
+                       (unsigned long)(pc + i));
                print_sh_insn((unsigned long)(pc + i), insn);
-               printk("\n");
+               pr_cont("\n");
        }
 
-       printk("\n");
+       pr_info("\n");
 }
index d481169..cd46a98 100644 (file)
@@ -3,60 +3,13 @@
  * Copyright (C) 2004 - 2007  Paul Mundt
  */
 #include <linux/mm.h>
-#include <linux/init.h>
 #include <linux/dma-noncoherent.h>
-#include <linux/module.h>
 #include <asm/cacheflush.h>
 #include <asm/addrspace.h>
 
-void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,
-               gfp_t gfp, unsigned long attrs)
+void arch_dma_prep_coherent(struct page *page, size_t size)
 {
-       void *ret, *ret_nocache;
-       int order = get_order(size);
-
-       gfp |= __GFP_ZERO;
-
-       ret = (void *)__get_free_pages(gfp, order);
-       if (!ret)
-               return NULL;
-
-       /*
-        * Pages from the page allocator may have data present in
-        * cache. So flush the cache before using uncached memory.
-        */
-       arch_sync_dma_for_device(virt_to_phys(ret), size,
-                       DMA_BIDIRECTIONAL);
-
-       ret_nocache = (void __force *)ioremap(virt_to_phys(ret), size);
-       if (!ret_nocache) {
-               free_pages((unsigned long)ret, order);
-               return NULL;
-       }
-
-       split_page(pfn_to_page(virt_to_phys(ret) >> PAGE_SHIFT), order);
-
-       *dma_handle = virt_to_phys(ret);
-       if (!WARN_ON(!dev))
-               *dma_handle -= PFN_PHYS(dev->dma_pfn_offset);
-
-       return ret_nocache;
-}
-
-void arch_dma_free(struct device *dev, size_t size, void *vaddr,
-               dma_addr_t dma_handle, unsigned long attrs)
-{
-       int order = get_order(size);
-       unsigned long pfn = (dma_handle >> PAGE_SHIFT);
-       int k;
-
-       if (!WARN_ON(!dev))
-               pfn += dev->dma_pfn_offset;
-
-       for (k = 0; k < (1 << order); k++)
-               __free_pages(pfn_to_page(pfn + k), 0);
-
-       iounmap(vaddr);
+       __flush_purge_region(page_address(page), size);
 }
 
 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
index a13c045..758a6c8 100644 (file)
@@ -16,8 +16,8 @@
 #include <asm/unwinder.h>
 #include <asm/stacktrace.h>
 
-void dump_mem(const char *str, const char *loglvl,
-             unsigned long bottom, unsigned long top)
+void dump_mem(const char *str, const char *loglvl, unsigned long bottom,
+             unsigned long top)
 {
        unsigned long p;
        int i;
@@ -31,23 +31,23 @@ void dump_mem(const char *str, const char *loglvl,
                        unsigned int val;
 
                        if (p < bottom || p >= top)
-                               printk("%s         ", loglvl);
+                               pr_cont("         ");
                        else {
                                if (__get_user(val, (unsigned int __user *)p)) {
-                                       printk("%s\n", loglvl);
+                                       pr_cont("\n");
                                        return;
                                }
-                               printk("%s%08x ", loglvl, val);
+                               pr_cont("%08x ", val);
                        }
                }
-               printk("%s\n", loglvl);
+               pr_cont("\n");
        }
 }
 
-void printk_address(unsigned long address, int reliable, const char *loglvl)
+void printk_address(unsigned long address, int reliable)
 {
-       printk("%s [<%p>] %s%pS\n", loglvl, (void *) address,
-                       reliable ? "" : "? ", (void *) address);
+       pr_cont(" [<%px>] %s%pS\n", (void *) address,
+               reliable ? "" : "? ", (void *) address);
 }
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
@@ -107,22 +107,16 @@ stack_reader_dump(struct task_struct *task, struct pt_regs *regs,
        }
 }
 
-static int print_trace_stack(void *data, char *name)
-{
-       printk("%s <%s> ", (char *)data, name);
-       return 0;
-}
-
 /*
  * Print one address/symbol entries per line.
  */
 static void print_trace_address(void *data, unsigned long addr, int reliable)
 {
-       printk_address(addr, reliable, (char *)data);
+       printk("%s", (char *)data);
+       printk_address(addr, reliable);
 }
 
 static const struct stacktrace_ops print_trace_ops = {
-       .stack = print_trace_stack,
        .address = print_trace_address,
 };
 
@@ -136,7 +130,7 @@ void show_trace(struct task_struct *tsk, unsigned long *sp,
 
        unwind_stack(tsk, regs, sp, &print_trace_ops, (void *)loglvl);
 
-       printk("%s\n", loglvl);
+       pr_cont("\n");
 
        if (!tsk)
                tsk = current;
index 9bac5bb..ad96310 100644 (file)
@@ -178,34 +178,6 @@ syscall_exit_work:
        bra     resume_userspace
         nop
 
-       .align  2
-syscall_trace_entry:
-       !                       Yes it is traced.
-       mov     r15, r4
-       mov.l   7f, r11         ! Call do_syscall_trace_enter which notifies
-       jsr     @r11            ! superior (will chomp R[0-7])
-        nop
-       mov.l   r0, @(OFF_R0,r15)       ! Save return value
-       !                       Reload R0-R4 from kernel stack, where the
-       !                       parent may have modified them using
-       !                       ptrace(POKEUSR).  (Note that R0-R2 are
-       !                       reloaded from the kernel stack by syscall_call
-       !                       below, so don't need to be reloaded here.)
-       !                       This allows the parent to rewrite system calls
-       !                       and args on the fly.
-       mov.l   @(OFF_R4,r15), r4   ! arg0
-       mov.l   @(OFF_R5,r15), r5
-       mov.l   @(OFF_R6,r15), r6
-       mov.l   @(OFF_R7,r15), r7   ! arg3
-       mov.l   @(OFF_R3,r15), r3   ! syscall_nr
-       !
-       mov.l   6f, r10                 ! Number of syscalls
-       cmp/hs  r10, r3
-       bf      syscall_call
-       mov     #-ENOSYS, r0
-       bra     syscall_exit
-        mov.l  r0, @(OFF_R0,r15)       ! Return value
-
 __restore_all:
        mov     #OFF_SR, r0
        mov.l   @(r0,r15), r0   ! get status register
@@ -388,6 +360,37 @@ syscall_exit:
        bf      syscall_exit_work
        bra     __restore_all
         nop
+
+       .align  2
+syscall_trace_entry:
+       !                       Yes it is traced.
+       mov     r15, r4
+       mov.l   7f, r11         ! Call do_syscall_trace_enter which notifies
+       jsr     @r11            ! superior (will chomp R[0-7])
+        nop
+       cmp/eq  #-1, r0
+       bt      syscall_exit
+       mov.l   r0, @(OFF_R0,r15)       ! Save return value
+       !                       Reload R0-R4 from kernel stack, where the
+       !                       parent may have modified them using
+       !                       ptrace(POKEUSR).  (Note that R0-R2 are
+       !                       reloaded from the kernel stack by syscall_call
+       !                       below, so don't need to be reloaded here.)
+       !                       This allows the parent to rewrite system calls
+       !                       and args on the fly.
+       mov.l   @(OFF_R4,r15), r4   ! arg0
+       mov.l   @(OFF_R5,r15), r5
+       mov.l   @(OFF_R6,r15), r6
+       mov.l   @(OFF_R7,r15), r7   ! arg3
+       mov.l   @(OFF_R3,r15), r3   ! syscall_nr
+       !
+       mov.l   6f, r10                 ! Number of syscalls
+       cmp/hs  r10, r3
+       bf      syscall_call
+       mov     #-ENOSYS, r0
+       bra     syscall_exit
+        mov.l  r0, @(OFF_R0,r15)       ! Return value
+
        .align  2
 #if !defined(CONFIG_CPU_SH2)
 1:     .long   TRA
index 037aab2..004ad01 100644 (file)
@@ -102,7 +102,6 @@ int register_trapped_io(struct trapped_io *tiop)
        pr_warn("unable to install trapped io filter\n");
        return -1;
 }
-EXPORT_SYMBOL_GPL(register_trapped_io);
 
 void __iomem *match_trapped_io_handler(struct list_head *list,
                                       unsigned long offset,
@@ -131,7 +130,6 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
        spin_unlock_irqrestore(&trapped_lock, flags);
        return NULL;
 }
-EXPORT_SYMBOL_GPL(match_trapped_io_handler);
 
 static struct trapped_io *lookup_tiop(unsigned long address)
 {
index ef9e2c9..0a0dff4 100644 (file)
@@ -8,31 +8,31 @@
 #include <linux/module.h>
 #include <linux/io.h>
 
-unsigned int ioread8(void __iomem *addr)
+unsigned int ioread8(const void __iomem *addr)
 {
        return readb(addr);
 }
 EXPORT_SYMBOL(ioread8);
 
-unsigned int ioread16(void __iomem *addr)
+unsigned int ioread16(const void __iomem *addr)
 {
        return readw(addr);
 }
 EXPORT_SYMBOL(ioread16);
 
-unsigned int ioread16be(void __iomem *addr)
+unsigned int ioread16be(const void __iomem *addr)
 {
        return be16_to_cpu(__raw_readw(addr));
 }
 EXPORT_SYMBOL(ioread16be);
 
-unsigned int ioread32(void __iomem *addr)
+unsigned int ioread32(const void __iomem *addr)
 {
        return readl(addr);
 }
 EXPORT_SYMBOL(ioread32);
 
-unsigned int ioread32be(void __iomem *addr)
+unsigned int ioread32be(const void __iomem *addr)
 {
        return be32_to_cpu(__raw_readl(addr));
 }
@@ -74,7 +74,7 @@ EXPORT_SYMBOL(iowrite32be);
  * convert to CPU byte order. We write in "IO byte
  * order" (we also don't have IO barriers).
  */
-static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
+static inline void mmio_insb(const void __iomem *addr, u8 *dst, int count)
 {
        while (--count >= 0) {
                u8 data = __raw_readb(addr);
@@ -83,7 +83,7 @@ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
        }
 }
 
-static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
+static inline void mmio_insw(const void __iomem *addr, u16 *dst, int count)
 {
        while (--count >= 0) {
                u16 data = __raw_readw(addr);
@@ -92,7 +92,7 @@ static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
        }
 }
 
-static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
+static inline void mmio_insl(const void __iomem *addr, u32 *dst, int count)
 {
        while (--count >= 0) {
                u32 data = __raw_readl(addr);
@@ -125,19 +125,19 @@ static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
        }
 }
 
-void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        mmio_insb(addr, dst, count);
 }
 EXPORT_SYMBOL(ioread8_rep);
 
-void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        mmio_insw(addr, dst, count);
 }
 EXPORT_SYMBOL(ioread16_rep);
 
-void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        mmio_insl(addr, dst, count);
 }
index 34f8cdb..f39446a 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <linux/module.h>
 #include <linux/io.h>
+#include <asm/io_trapped.h>
 
 unsigned long sh_io_port_base __read_mostly = -1;
 EXPORT_SYMBOL(sh_io_port_base);
index 76bd895..d606679 100644 (file)
@@ -65,10 +65,10 @@ static int __init early_parse_mv(char *from)
 
        mvp = get_mv_byname(mv_name);
        if (unlikely(!mvp)) {
-               printk("Available vectors:\n\n\t'%s', ", sh_mv.mv_name);
+               pr_info("Available vectors:\n\n\t'%s', ", sh_mv.mv_name);
                for_each_mv(mvp)
-                       printk("'%s', ", mvp->mv_name);
-               printk("\n\n");
+                       pr_cont("'%s', ", mvp->mv_name);
+               pr_cont("\n\n");
                panic("Failed to select machvec '%s' -- halting.\n",
                      mv_name);
        } else
@@ -105,7 +105,7 @@ void __init sh_mv_setup(void)
                        sh_mv = *(struct sh_machine_vector *)&__machvec_start;
        }
 
-       printk(KERN_NOTICE "Booting machvec: %s\n", get_system_type());
+       pr_notice("Booting machvec: %s\n", get_system_type());
 
        /*
         * Manually walk the vec, fill in anything that the board hasn't yet
index 6281f2f..c9d3aa1 100644 (file)
 #include <asm/unwinder.h>
 #include <asm/ptrace.h>
 
-static int callchain_stack(void *data, char *name)
-{
-       return 0;
-}
-
 static void callchain_address(void *data, unsigned long addr, int reliable)
 {
        struct perf_callchain_entry_ctx *entry = data;
@@ -25,7 +20,6 @@ static void callchain_address(void *data, unsigned long addr, int reliable)
 }
 
 static const struct stacktrace_ops callchain_ops = {
-       .stack          = callchain_stack,
        .address        = callchain_address,
 };
 
index a432c36..80a5d1c 100644 (file)
 
 void show_regs(struct pt_regs * regs)
 {
-       printk("\n");
+       pr_info("\n");
        show_regs_print_info(KERN_DEFAULT);
 
-       printk("PC is at %pS\n", (void *)instruction_pointer(regs));
-       printk("PR is at %pS\n", (void *)regs->pr);
+       pr_info("PC is at %pS\n", (void *)instruction_pointer(regs));
+       pr_info("PR is at %pS\n", (void *)regs->pr);
 
-       printk("PC  : %08lx SP  : %08lx SR  : %08lx ",
-              regs->pc, regs->regs[15], regs->sr);
+       pr_info("PC  : %08lx SP  : %08lx SR  : %08lx ", regs->pc,
+               regs->regs[15], regs->sr);
 #ifdef CONFIG_MMU
-       printk("TEA : %08x\n", __raw_readl(MMU_TEA));
+       pr_cont("TEA : %08x\n", __raw_readl(MMU_TEA));
 #else
-       printk("\n");
+       pr_cont("\n");
 #endif
 
-       printk("R0  : %08lx R1  : %08lx R2  : %08lx R3  : %08lx\n",
-              regs->regs[0],regs->regs[1],
-              regs->regs[2],regs->regs[3]);
-       printk("R4  : %08lx R5  : %08lx R6  : %08lx R7  : %08lx\n",
-              regs->regs[4],regs->regs[5],
-              regs->regs[6],regs->regs[7]);
-       printk("R8  : %08lx R9  : %08lx R10 : %08lx R11 : %08lx\n",
-              regs->regs[8],regs->regs[9],
-              regs->regs[10],regs->regs[11]);
-       printk("R12 : %08lx R13 : %08lx R14 : %08lx\n",
-              regs->regs[12],regs->regs[13],
-              regs->regs[14]);
-       printk("MACH: %08lx MACL: %08lx GBR : %08lx PR  : %08lx\n",
-              regs->mach, regs->macl, regs->gbr, regs->pr);
+       pr_info("R0  : %08lx R1  : %08lx R2  : %08lx R3  : %08lx\n",
+               regs->regs[0], regs->regs[1], regs->regs[2], regs->regs[3]);
+       pr_info("R4  : %08lx R5  : %08lx R6  : %08lx R7  : %08lx\n",
+               regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
+       pr_info("R8  : %08lx R9  : %08lx R10 : %08lx R11 : %08lx\n",
+               regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
+       pr_info("R12 : %08lx R13 : %08lx R14 : %08lx\n",
+               regs->regs[12], regs->regs[13], regs->regs[14]);
+       pr_info("MACH: %08lx MACL: %08lx GBR : %08lx PR  : %08lx\n",
+               regs->mach, regs->macl, regs->gbr, regs->pr);
 
        show_trace(NULL, (unsigned long *)regs->regs[15], regs, KERN_DEFAULT);
        show_code(regs);
index 609b7c9..b05bf92 100644 (file)
@@ -457,8 +457,6 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
 {
        long ret = 0;
 
-       secure_computing_strict(regs->regs[0]);
-
        if (test_thread_flag(TIF_SYSCALL_TRACE) &&
            tracehook_report_syscall_entry(regs))
                /*
@@ -468,6 +466,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
                 */
                ret = -1L;
 
+       if (secure_computing() == -1)
+               return -1;
+
        if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
                trace_sys_enter(regs, regs->regs[0]);
 
index 2950b19..daf0b53 100644 (file)
 #include <asm/ptrace.h>
 #include <asm/stacktrace.h>
 
-static int save_stack_stack(void *data, char *name)
-{
-       return 0;
-}
-
 /*
  * Save stack-backtrace addresses into a stack_trace buffer.
  */
@@ -40,7 +35,6 @@ static void save_stack_address(void *data, unsigned long addr, int reliable)
 }
 
 static const struct stacktrace_ops save_stack_ops = {
-       .stack = save_stack_stack,
        .address = save_stack_address,
 };
 
@@ -73,7 +67,6 @@ save_stack_address_nosched(void *data, unsigned long addr, int reliable)
 }
 
 static const struct stacktrace_ops save_stack_ops_nosched = {
-       .stack = save_stack_stack,
        .address = save_stack_address_nosched,
 };
 
index 96848db..ae0a00b 100644 (file)
 146    common  writev                          sys_writev
 147    common  getsid                          sys_getsid
 148    common  fdatasync                       sys_fdatasync
-149    common  _sysctl                         sys_sysctl
+149    common  _sysctl                         sys_ni_syscall
 150    common  mlock                           sys_mlock
 151    common  munlock                         sys_munlock
 152    common  mlockall                        sys_mlockall
index d0abbe5..eb473d3 100644 (file)
@@ -30,5 +30,3 @@ memset-$(CONFIG_CPU_SH4)      := memset-sh4.o
 lib-$(CONFIG_MMU)              += copy_page.o __clear_user.o
 lib-$(CONFIG_MCOUNT)           += mcount.o
 lib-y                          += $(memcpy-y) $(memset-y) $(udivsi3-y)
-
-ccflags-y := -Werror
index 540e670..dad8e6a 100644 (file)
@@ -29,7 +29,6 @@ void __delay(unsigned long loops)
                : "0" (loops)
                : "t");
 }
-EXPORT_SYMBOL(__delay);
 
 inline void __const_udelay(unsigned long xloops)
 {
index 487da0f..f69ddc7 100644 (file)
@@ -43,5 +43,3 @@ obj-$(CONFIG_UNCACHED_MAPPING)        += uncached.o
 obj-$(CONFIG_HAVE_SRAM_POOL)   += sram.o
 
 GCOV_PROFILE_pmb.o := n
-
-ccflags-y := -Werror
index 3169a34..0de206c 100644 (file)
@@ -57,8 +57,6 @@ int __init platform_resource_setup_memory(struct platform_device *pdev,
                return -ENOMEM;
        }
 
-       memset(buf, 0, memsize);
-
        r->flags = IORESOURCE_MEM;
        r->start = dma_handle;
        r->end = r->start + memsize - 1;
index 482668a..88a1f45 100644 (file)
@@ -208,13 +208,12 @@ show_fault_oops(struct pt_regs *regs, unsigned long address)
        if (!oops_may_print())
                return;
 
-       printk(KERN_ALERT "PC:");
        pr_alert("BUG: unable to handle kernel %s at %08lx\n",
                 address < PAGE_SIZE ? "NULL pointer dereference"
                                     : "paging request",
                 address);
        pr_alert("PC:");
-       printk_address(regs->pc, 1, KERN_ALERT);
+       printk_address(regs->pc, 1);
 
        show_pte(NULL, address);
 }
index cd13793..4735176 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/cache.h>
 #include <asm/pgalloc.h>
 #include <linux/sizes.h>
+#include "ioremap.h"
 
 pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
index f6d0224..2134258 100644 (file)
 #include <linux/mm.h>
 #include <linux/pci.h>
 #include <linux/io.h>
+#include <asm/io_trapped.h>
 #include <asm/page.h>
 #include <asm/pgalloc.h>
 #include <asm/addrspace.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 #include <asm/mmu.h>
+#include "ioremap.h"
+
+/*
+ * On 32-bit SH, we traditionally have the whole physical address space mapped
+ * at all times (as MIPS does), so "ioremap()" and "iounmap()" do not need to do
+ * anything but place the address in the proper segment.  This is true for P1
+ * and P2 addresses, as well as some P3 ones.  However, most of the P3 addresses
+ * and newer cores using extended addressing need to map through page tables, so
+ * the ioremap() implementation becomes a bit more complicated.
+ */
+#ifdef CONFIG_29BIT
+static void __iomem *
+__ioremap_29bit(phys_addr_t offset, unsigned long size, pgprot_t prot)
+{
+       phys_addr_t last_addr = offset + size - 1;
+
+       /*
+        * For P1 and P2 space this is trivial, as everything is already
+        * mapped. Uncached access for P1 addresses are done through P2.
+        * In the P3 case or for addresses outside of the 29-bit space,
+        * mapping must be done by the PMB or by using page tables.
+        */
+       if (likely(PXSEG(offset) < P3SEG && PXSEG(last_addr) < P3SEG)) {
+               u64 flags = pgprot_val(prot);
+
+               /*
+                * Anything using the legacy PTEA space attributes needs
+                * to be kicked down to page table mappings.
+                */
+               if (unlikely(flags & _PAGE_PCC_MASK))
+                       return NULL;
+               if (unlikely(flags & _PAGE_CACHABLE))
+                       return (void __iomem *)P1SEGADDR(offset);
+
+               return (void __iomem *)P2SEGADDR(offset);
+       }
+
+       /* P4 above the store queues are always mapped. */
+       if (unlikely(offset >= P3_ADDR_MAX))
+               return (void __iomem *)P4SEGADDR(offset);
+
+       return NULL;
+}
+#else
+#define __ioremap_29bit(offset, size, prot)            NULL
+#endif /* CONFIG_29BIT */
 
 /*
  * Remap an arbitrary physical address space into the kernel virtual
@@ -42,6 +89,14 @@ __ioremap_caller(phys_addr_t phys_addr, unsigned long size,
        unsigned long offset, last_addr, addr, orig_addr;
        void __iomem *mapped;
 
+       mapped = __ioremap_trapped(phys_addr, size);
+       if (mapped)
+               return mapped;
+
+       mapped = __ioremap_29bit(phys_addr, size, pgprot);
+       if (mapped)
+               return mapped;
+
        /* Don't allow wraparound or zero size */
        last_addr = phys_addr + size - 1;
        if (!size || last_addr < phys_addr)
diff --git a/arch/sh/mm/ioremap.h b/arch/sh/mm/ioremap.h
new file mode 100644 (file)
index 0000000..f2544e7
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _SH_MM_IORMEMAP_H
+#define _SH_MM_IORMEMAP_H 1
+
+#ifdef CONFIG_IOREMAP_FIXED
+void __iomem *ioremap_fixed(phys_addr_t, unsigned long, pgprot_t);
+int iounmap_fixed(void __iomem *);
+void ioremap_fixed_init(void);
+#else
+static inline void __iomem *
+ioremap_fixed(phys_addr_t phys_addr, unsigned long size, pgprot_t prot)
+{
+       BUG();
+       return NULL;
+}
+static inline void ioremap_fixed_init(void)
+{
+}
+static inline int iounmap_fixed(void __iomem *addr)
+{
+       return -EINVAL;
+}
+#endif /* CONFIG_IOREMAP_FIXED */
+#endif /* _SH_MM_IORMEMAP_H */
index aab3f82..136113b 100644 (file)
@@ -23,6 +23,7 @@
 #include <asm/tlbflush.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
+#include "ioremap.h"
 
 struct ioremap_map {
        void __iomem *addr;
index 5c8f924..cf7ce4b 100644 (file)
@@ -2,8 +2,6 @@
 #include <linux/mm.h>
 #include <linux/slab.h>
 
-#define PGALLOC_GFP GFP_KERNEL | __GFP_ZERO
-
 static struct kmem_cache *pgd_cachep;
 #if PAGETABLE_LEVELS > 2
 static struct kmem_cache *pmd_cachep;
@@ -13,6 +11,7 @@ void pgd_ctor(void *x)
 {
        pgd_t *pgd = x;
 
+       memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t));
        memcpy(pgd + USER_PTRS_PER_PGD,
               swapper_pg_dir + USER_PTRS_PER_PGD,
               (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
@@ -32,7 +31,7 @@ void pgtable_cache_init(void)
 
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
-       return kmem_cache_alloc(pgd_cachep, PGALLOC_GFP);
+       return kmem_cache_alloc(pgd_cachep, GFP_KERNEL);
 }
 
 void pgd_free(struct mm_struct *mm, pgd_t *pgd)
@@ -48,7 +47,7 @@ void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 
 pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-       return kmem_cache_alloc(pmd_cachep, PGALLOC_GFP);
+       return kmem_cache_alloc(pmd_cachep, GFP_KERNEL | __GFP_ZERO);
 }
 
 void pmd_free(struct mm_struct *mm, pmd_t *pmd)
index f1205f9..cc16cf8 100644 (file)
 #include <asm/sections.h>
 #include <asm/stacktrace.h>
 
-static int backtrace_stack(void *data, char *name)
-{
-       /* Yes, we want all stacks */
-       return 0;
-}
-
 static void backtrace_address(void *data, unsigned long addr, int reliable)
 {
        unsigned int *depth = data;
@@ -34,7 +28,6 @@ static void backtrace_address(void *data, unsigned long addr, int reliable)
 }
 
 static struct stacktrace_ops backtrace_ops = {
-       .stack = backtrace_stack,
        .address = backtrace_address,
 };
 
index 569977e..29e6488 100644 (file)
@@ -46,7 +46,6 @@ X3PROTO                       SH_X3PROTO
 MAGICPANELR2           SH_MAGIC_PANEL_R2
 R2D_PLUS               RTS7751R2D_PLUS
 R2D_1                  RTS7751R2D_1
-CAYMAN                 SH_CAYMAN
 SDK7780                        SH_SDK7780
 MIGOR                  SH_MIGOR
 RSK7201                        SH_RSK7201
index 46024e8..4af114e 100644 (file)
 249    64      nanosleep               sys_nanosleep
 250    32      mremap                  sys_mremap
 250    64      mremap                  sys_64_mremap
-251    common  _sysctl                 sys_sysctl                      compat_sys_sysctl
+251    common  _sysctl                 sys_ni_syscall
 252    common  getsid                  sys_getsid
 253    common  fdatasync               sys_fdatasync
 254    32      nfsservctl              sys_ni_syscall                  sys_nis_syscall
index ef69be1..eb51fec 100644 (file)
@@ -14,6 +14,7 @@ config UML
        select HAVE_FUTEX_CMPXCHG if FUTEX
        select HAVE_DEBUG_KMEMLEAK
        select HAVE_DEBUG_BUGVERBOSE
+       select NO_DMA
        select GENERIC_IRQ_SHOW
        select GENERIC_CPU_DEVICES
        select GENERIC_CLOCKEVENTS
@@ -167,9 +168,6 @@ config MMAPPER
          This driver allows a host file to be used as emulated IO memory inside
          UML.
 
-config NO_DMA
-       def_bool y
-
 config PGTABLE_LEVELS
        int
        default 3 if 3_LEVEL_PGTABLES
index 9a28495..7101ac6 100644 (file)
@@ -209,6 +209,7 @@ config X86
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
        select MMU_GATHER_RCU_TABLE_FREE                if PARAVIRT
+       select HAVE_POSIX_CPU_TIMERS_TASK_WORK
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RELIABLE_STACKTRACE         if X86_64 && (UNWINDER_FRAME_POINTER || UNWINDER_ORC) && STACK_VALIDATION
        select HAVE_FUNCTION_ARG_ACCESS_API
index 39e592d..e478e40 100644 (file)
 #define STATIC         static
 
 /*
- * Use normal definitions of mem*() from string.c. There are already
- * included header files which expect a definition of memset() and by
- * the time we define memset macro, it is too late.
+ * Provide definitions of memzero and memmove as some of the decompressors will
+ * try to define their own functions if these are not defined as macros.
  */
-#undef memcpy
-#undef memset
 #define memzero(s, n)  memset((s), 0, (n))
 #define memmove                memmove
 
index 995f7b7..a232da4 100644 (file)
@@ -11,10 +11,7 @@ void *memcpy(void *dst, const void *src, size_t len);
 void *memset(void *dst, int c, size_t len);
 int memcmp(const void *s1, const void *s2, size_t len);
 
-/*
- * Access builtin version by default. If one needs to use optimized version,
- * do "undef memcpy" in .c file and link against right string.c
- */
+/* Access builtin version by default. */
 #define memcpy(d,s,l) __builtin_memcpy(d,s,l)
 #define memset(d,c,l) __builtin_memset(d,c,l)
 #define memcmp __builtin_memcmp
index 29b7d52..df8c017 100644 (file)
 
 .macro SWITCH_TO_KERNEL_STACK
 
-       ALTERNATIVE     "", "jmp .Lend_\@", X86_FEATURE_XENPV
-
        BUG_IF_WRONG_CR3
 
        SWITCH_TO_KERNEL_CR3 scratch_reg=%eax
  */
 .macro SWITCH_TO_ENTRY_STACK
 
-       ALTERNATIVE     "", "jmp .Lend_\@", X86_FEATURE_XENPV
-
        /* Bytes to copy */
        movl    $PTREGS_SIZE, %ecx
 
@@ -872,17 +868,6 @@ SYM_ENTRY(__begin_SYSENTER_singlestep_region, SYM_L_GLOBAL, SYM_A_NONE)
  * will ignore all of the single-step traps generated in this range.
  */
 
-#ifdef CONFIG_XEN_PV
-/*
- * Xen doesn't set %esp to be precisely what the normal SYSENTER
- * entry point expects, so fix it up before using the normal path.
- */
-SYM_CODE_START(xen_sysenter_target)
-       addl    $5*4, %esp                      /* remove xen-provided frame */
-       jmp     .Lsysenter_past_esp
-SYM_CODE_END(xen_sysenter_target)
-#endif
-
 /*
  * 32-bit SYSENTER entry.
  *
@@ -965,9 +950,8 @@ SYM_FUNC_START(entry_SYSENTER_32)
 
        movl    %esp, %eax
        call    do_SYSENTER_32
-       /* XEN PV guests always use IRET path */
-       ALTERNATIVE "testl %eax, %eax; jz .Lsyscall_32_done", \
-                   "jmp .Lsyscall_32_done", X86_FEATURE_XENPV
+       testl   %eax, %eax
+       jz      .Lsyscall_32_done
 
        STACKLEAK_ERASE
 
@@ -1165,95 +1149,6 @@ SYM_FUNC_END(entry_INT80_32)
 #endif
 .endm
 
-#ifdef CONFIG_PARAVIRT
-SYM_CODE_START(native_iret)
-       iret
-       _ASM_EXTABLE(native_iret, asm_iret_error)
-SYM_CODE_END(native_iret)
-#endif
-
-#ifdef CONFIG_XEN_PV
-/*
- * See comment in entry_64.S for further explanation
- *
- * Note: This is not an actual IDT entry point. It's a XEN specific entry
- * point and therefore named to match the 64-bit trampoline counterpart.
- */
-SYM_FUNC_START(xen_asm_exc_xen_hypervisor_callback)
-       /*
-        * Check to see if we got the event in the critical
-        * region in xen_iret_direct, after we've reenabled
-        * events and checked for pending events.  This simulates
-        * iret instruction's behaviour where it delivers a
-        * pending interrupt when enabling interrupts:
-        */
-       cmpl    $xen_iret_start_crit, (%esp)
-       jb      1f
-       cmpl    $xen_iret_end_crit, (%esp)
-       jae     1f
-       call    xen_iret_crit_fixup
-1:
-       pushl   $-1                             /* orig_ax = -1 => not a system call */
-       SAVE_ALL
-       ENCODE_FRAME_POINTER
-
-       mov     %esp, %eax
-       call    xen_pv_evtchn_do_upcall
-       jmp     handle_exception_return
-SYM_FUNC_END(xen_asm_exc_xen_hypervisor_callback)
-
-/*
- * Hypervisor uses this for application faults while it executes.
- * We get here for two reasons:
- *  1. Fault while reloading DS, ES, FS or GS
- *  2. Fault while executing IRET
- * Category 1 we fix up by reattempting the load, and zeroing the segment
- * register if the load fails.
- * Category 2 we fix up by jumping to do_iret_error. We cannot use the
- * normal Linux return path in this case because if we use the IRET hypercall
- * to pop the stack frame we end up in an infinite loop of failsafe callbacks.
- * We distinguish between categories by maintaining a status value in EAX.
- */
-SYM_FUNC_START(xen_failsafe_callback)
-       pushl   %eax
-       movl    $1, %eax
-1:     mov     4(%esp), %ds
-2:     mov     8(%esp), %es
-3:     mov     12(%esp), %fs
-4:     mov     16(%esp), %gs
-       /* EAX == 0 => Category 1 (Bad segment)
-          EAX != 0 => Category 2 (Bad IRET) */
-       testl   %eax, %eax
-       popl    %eax
-       lea     16(%esp), %esp
-       jz      5f
-       jmp     asm_iret_error
-5:     pushl   $-1                             /* orig_ax = -1 => not a system call */
-       SAVE_ALL
-       ENCODE_FRAME_POINTER
-       jmp     handle_exception_return
-
-.section .fixup, "ax"
-6:     xorl    %eax, %eax
-       movl    %eax, 4(%esp)
-       jmp     1b
-7:     xorl    %eax, %eax
-       movl    %eax, 8(%esp)
-       jmp     2b
-8:     xorl    %eax, %eax
-       movl    %eax, 12(%esp)
-       jmp     3b
-9:     xorl    %eax, %eax
-       movl    %eax, 16(%esp)
-       jmp     4b
-.previous
-       _ASM_EXTABLE(1b, 6b)
-       _ASM_EXTABLE(2b, 7b)
-       _ASM_EXTABLE(3b, 8b)
-       _ASM_EXTABLE(4b, 9b)
-SYM_FUNC_END(xen_failsafe_callback)
-#endif /* CONFIG_XEN_PV */
-
 SYM_CODE_START_LOCAL_NOALIGN(handle_exception)
        /* the function address is in %gs's slot on the stack */
        SAVE_ALL switch_stacks=1 skip_gs=1 unwind_espfix=1
index e31a752..9d11028 100644 (file)
 146    i386    writev                  sys_writev                      compat_sys_writev
 147    i386    getsid                  sys_getsid
 148    i386    fdatasync               sys_fdatasync
-149    i386    _sysctl                 sys_sysctl                      compat_sys_sysctl
+149    i386    _sysctl                 sys_ni_syscall
 150    i386    mlock                   sys_mlock
 151    i386    munlock                 sys_munlock
 152    i386    mlockall                sys_mlockall
index 9d82078..f30d6ae 100644 (file)
 153    common  vhangup                 sys_vhangup
 154    common  modify_ldt              sys_modify_ldt
 155    common  pivot_root              sys_pivot_root
-156    64      _sysctl                 sys_sysctl
+156    64      _sysctl                 sys_ni_syscall
 157    common  prctl                   sys_prctl
 158    common  arch_prctl              sys_arch_prctl
 159    common  adjtimex                sys_adjtimex
index e78047d..2cbd399 100644 (file)
@@ -16,33 +16,3 @@ ELFNOTE_START(Linux, 0, "a")
 ELFNOTE_END
 
 BUILD_SALT
-
-#ifdef CONFIG_XEN
-/*
- * Add a special note telling glibc's dynamic linker a fake hardware
- * flavor that it will use to choose the search path for libraries in the
- * same way it uses real hardware capabilities like "mmx".
- * We supply "nosegneg" as the fake capability, to indicate that we
- * do not like negative offsets in instructions using segment overrides,
- * since we implement those inefficiently.  This makes it possible to
- * install libraries optimized to avoid those access patterns in someplace
- * like /lib/i686/tls/nosegneg.  Note that an /etc/ld.so.conf.d/file
- * corresponding to the bits here is needed to make ldconfig work right.
- * It should contain:
- *     hwcap 1 nosegneg
- * to match the mapping of bit to name that we give here.
- *
- * At runtime, the fake hardware feature will be considered to be present
- * if its bit is set in the mask word.  So, we start with the mask 0, and
- * at boot time we set VDSO_NOTE_NONEGSEG_BIT if running under Xen.
- */
-
-#include "../../xen/vdso.h"    /* Defines VDSO_NOTE_NONEGSEG_BIT.  */
-
-ELFNOTE_START(GNU, 2, "a")
-       .long 1                 /* ncaps */
-VDSO32_NOTE_MASK:              /* Symbol used by arch/x86/xen/setup.c */
-       .long 0                 /* mask */
-       .byte VDSO_NOTE_NONEGSEG_BIT; .asciz "nosegneg" /* bit, name */
-ELFNOTE_END
-#endif
index 68b3882..67b411f 100644 (file)
@@ -130,11 +130,17 @@ struct rapl_pmus {
        struct rapl_pmu         *pmus[];
 };
 
+enum rapl_unit_quirk {
+       RAPL_UNIT_QUIRK_NONE,
+       RAPL_UNIT_QUIRK_INTEL_HSW,
+       RAPL_UNIT_QUIRK_INTEL_SPR,
+};
+
 struct rapl_model {
        struct perf_msr *rapl_msrs;
        unsigned long   events;
        unsigned int    msr_power_unit;
-       bool            apply_quirk;
+       enum rapl_unit_quirk    unit_quirk;
 };
 
  /* 1/2^hw_unit Joule */
@@ -612,14 +618,28 @@ static int rapl_check_hw_unit(struct rapl_model *rm)
        for (i = 0; i < NR_RAPL_DOMAINS; i++)
                rapl_hw_unit[i] = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
 
+       switch (rm->unit_quirk) {
        /*
         * DRAM domain on HSW server and KNL has fixed energy unit which can be
         * different than the unit from power unit MSR. See
         * "Intel Xeon Processor E5-1600 and E5-2600 v3 Product Families, V2
         * of 2. Datasheet, September 2014, Reference Number: 330784-001 "
         */
-       if (rm->apply_quirk)
+       case RAPL_UNIT_QUIRK_INTEL_HSW:
+               rapl_hw_unit[PERF_RAPL_RAM] = 16;
+               break;
+       /*
+        * SPR shares the same DRAM domain energy unit as HSW, plus it
+        * also has a fixed energy unit for Psys domain.
+        */
+       case RAPL_UNIT_QUIRK_INTEL_SPR:
                rapl_hw_unit[PERF_RAPL_RAM] = 16;
+               rapl_hw_unit[PERF_RAPL_PSYS] = 0;
+               break;
+       default:
+               break;
+       }
+
 
        /*
         * Calculate the timer rate:
@@ -665,7 +685,7 @@ static const struct attribute_group *rapl_attr_update[] = {
        &rapl_events_pkg_group,
        &rapl_events_ram_group,
        &rapl_events_gpu_group,
-       &rapl_events_gpu_group,
+       &rapl_events_psys_group,
        NULL,
 };
 
@@ -698,7 +718,6 @@ static struct rapl_model model_snb = {
        .events         = BIT(PERF_RAPL_PP0) |
                          BIT(PERF_RAPL_PKG) |
                          BIT(PERF_RAPL_PP1),
-       .apply_quirk    = false,
        .msr_power_unit = MSR_RAPL_POWER_UNIT,
        .rapl_msrs      = intel_rapl_msrs,
 };
@@ -707,7 +726,6 @@ static struct rapl_model model_snbep = {
        .events         = BIT(PERF_RAPL_PP0) |
                          BIT(PERF_RAPL_PKG) |
                          BIT(PERF_RAPL_RAM),
-       .apply_quirk    = false,
        .msr_power_unit = MSR_RAPL_POWER_UNIT,
        .rapl_msrs      = intel_rapl_msrs,
 };
@@ -717,7 +735,6 @@ static struct rapl_model model_hsw = {
                          BIT(PERF_RAPL_PKG) |
                          BIT(PERF_RAPL_RAM) |
                          BIT(PERF_RAPL_PP1),
-       .apply_quirk    = false,
        .msr_power_unit = MSR_RAPL_POWER_UNIT,
        .rapl_msrs      = intel_rapl_msrs,
 };
@@ -726,7 +743,7 @@ static struct rapl_model model_hsx = {
        .events         = BIT(PERF_RAPL_PP0) |
                          BIT(PERF_RAPL_PKG) |
                          BIT(PERF_RAPL_RAM),
-       .apply_quirk    = true,
+       .unit_quirk     = RAPL_UNIT_QUIRK_INTEL_HSW,
        .msr_power_unit = MSR_RAPL_POWER_UNIT,
        .rapl_msrs      = intel_rapl_msrs,
 };
@@ -734,7 +751,7 @@ static struct rapl_model model_hsx = {
 static struct rapl_model model_knl = {
        .events         = BIT(PERF_RAPL_PKG) |
                          BIT(PERF_RAPL_RAM),
-       .apply_quirk    = true,
+       .unit_quirk     = RAPL_UNIT_QUIRK_INTEL_HSW,
        .msr_power_unit = MSR_RAPL_POWER_UNIT,
        .rapl_msrs      = intel_rapl_msrs,
 };
@@ -745,14 +762,22 @@ static struct rapl_model model_skl = {
                          BIT(PERF_RAPL_RAM) |
                          BIT(PERF_RAPL_PP1) |
                          BIT(PERF_RAPL_PSYS),
-       .apply_quirk    = false,
+       .msr_power_unit = MSR_RAPL_POWER_UNIT,
+       .rapl_msrs      = intel_rapl_msrs,
+};
+
+static struct rapl_model model_spr = {
+       .events         = BIT(PERF_RAPL_PP0) |
+                         BIT(PERF_RAPL_PKG) |
+                         BIT(PERF_RAPL_RAM) |
+                         BIT(PERF_RAPL_PSYS),
+       .unit_quirk     = RAPL_UNIT_QUIRK_INTEL_SPR,
        .msr_power_unit = MSR_RAPL_POWER_UNIT,
        .rapl_msrs      = intel_rapl_msrs,
 };
 
 static struct rapl_model model_amd_fam17h = {
        .events         = BIT(PERF_RAPL_PKG),
-       .apply_quirk    = false,
        .msr_power_unit = MSR_AMD_RAPL_POWER_UNIT,
        .rapl_msrs      = amd_rapl_msrs,
 };
@@ -787,6 +812,7 @@ static const struct x86_cpu_id rapl_model_match[] __initconst = {
        X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X,           &model_hsx),
        X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE_L,         &model_skl),
        X86_MATCH_INTEL_FAM6_MODEL(COMETLAKE,           &model_skl),
+       X86_MATCH_INTEL_FAM6_MODEL(SAPPHIRERAPIDS_X,    &model_spr),
        X86_MATCH_VENDOR_FAM(AMD,       0x17,           &model_amd_fam17h),
        X86_MATCH_VENDOR_FAM(HYGON,     0x18,           &model_amd_fam17h),
        {},
index 60b944d..4f77b8f 100644 (file)
@@ -8,6 +8,7 @@
 #include <asm/io.h>
 #include <asm/hyperv-tlfs.h>
 #include <asm/nospec-branch.h>
+#include <asm/paravirt.h>
 
 typedef int (*hyperv_fill_flush_list_func)(
                struct hv_guest_mapping_flush_list *flush,
@@ -54,6 +55,17 @@ typedef int (*hyperv_fill_flush_list_func)(
        vclocks_set_used(VDSO_CLOCKMODE_HVCLOCK);
 #define hv_get_raw_timer() rdtsc_ordered()
 
+/*
+ * Reference to pv_ops must be inline so objtool
+ * detection of noinstr violations can work correctly.
+ */
+static __always_inline void hv_setup_sched_clock(void *sched_clock)
+{
+#ifdef CONFIG_PARAVIRT
+       pv_ops.time.sched_clock = sched_clock;
+#endif
+}
+
 void hyperv_vector_handler(struct pt_regs *regs);
 
 static inline void hv_enable_stimer0_percpu_irq(int irq) {}
index 6e81788..28996fe 100644 (file)
@@ -25,7 +25,7 @@ void entry_SYSENTER_compat(void);
 void __end_entry_SYSENTER_compat(void);
 void entry_SYSCALL_compat(void);
 void entry_INT80_compat(void);
-#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV)
+#ifdef CONFIG_XEN_PV
 void xen_entry_INT80_compat(void);
 #endif
 #endif
index 6669164..9646c30 100644 (file)
@@ -301,7 +301,7 @@ static inline void vdso_read_cpunode(unsigned *cpu, unsigned *node)
 extern const char early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE];
 extern void early_ignore_irq(void);
 
-#if defined(CONFIG_X86_64) && defined(CONFIG_XEN_PV)
+#ifdef CONFIG_XEN_PV
 extern const char xen_early_idt_handler_array[NUM_EXCEPTION_VECTORS][XEN_EARLY_IDT_HANDLER_SIZE];
 #endif
 
index fb81fea..df01d73 100644 (file)
@@ -241,7 +241,8 @@ static u64 vread_hvclock(void)
 }
 #endif
 
-static inline u64 __arch_get_hw_counter(s32 clock_mode)
+static inline u64 __arch_get_hw_counter(s32 clock_mode,
+                                       const struct vdso_data *vd)
 {
        if (likely(clock_mode == VDSO_CLOCKMODE_TSC))
                return (u64)rdtsc_ordered();
index d117553..c3daf0a 100644 (file)
@@ -875,8 +875,6 @@ static void *__text_poke(void *addr, const void *opcode, size_t len)
         */
        BUG_ON(!pages[0] || (cross_page_boundary && !pages[1]));
 
-       local_irq_save(flags);
-
        /*
         * Map the page without the global bit, as TLB flushing is done with
         * flush_tlb_mm_range(), which is intended for non-global PTEs.
@@ -893,6 +891,8 @@ static void *__text_poke(void *addr, const void *opcode, size_t len)
         */
        VM_BUG_ON(!ptep);
 
+       local_irq_save(flags);
+
        pte = mk_pte(pages[0], pgprot);
        set_pte_at(poking_mm, poking_addr, ptep, pte);
 
@@ -942,8 +942,8 @@ static void *__text_poke(void *addr, const void *opcode, size_t len)
         */
        BUG_ON(memcmp(addr, opcode, len));
 
-       pte_unmap_unlock(ptep, ptl);
        local_irq_restore(flags);
+       pte_unmap_unlock(ptep, ptl);
        return addr;
 }
 
index 1da9b1c..0b2c039 100644 (file)
 
 #include <linux/interrupt.h>
 #include <asm/apic.h>
+#include <asm/cpufeatures.h>
 #include <asm/desc.h>
 #include <asm/hypervisor.h>
 #include <asm/idtentry.h>
 #include <asm/irq_regs.h>
 
-static uint32_t __init acrn_detect(void)
+static u32 __init acrn_detect(void)
 {
-       return hypervisor_cpuid_base("ACRNACRNACRN\0\0", 0);
+       return hypervisor_cpuid_base("ACRNACRNACRN", 0);
 }
 
 static void __init acrn_init_platform(void)
@@ -29,12 +30,7 @@ static void __init acrn_init_platform(void)
 
 static bool acrn_x2apic_available(void)
 {
-       /*
-        * x2apic is not supported for now. Future enablement will have to check
-        * X86_FEATURE_X2APIC to determine whether x2apic is supported in the
-        * guest.
-        */
-       return false;
+       return boot_cpu_has(X86_FEATURE_X2APIC);
 }
 
 static void (*acrn_intr_handler)(void);
index f0b743a..d3f0db4 100644 (file)
@@ -31,6 +31,7 @@
 #include <asm/intel-family.h>
 #include <asm/e820/api.h>
 #include <asm/hypervisor.h>
+#include <asm/tlbflush.h>
 
 #include "cpu.h"
 
@@ -1549,7 +1550,12 @@ static ssize_t l1tf_show_state(char *buf)
 
 static ssize_t itlb_multihit_show_state(char *buf)
 {
-       if (itlb_multihit_kvm_mitigation)
+       if (!boot_cpu_has(X86_FEATURE_MSR_IA32_FEAT_CTL) ||
+           !boot_cpu_has(X86_FEATURE_VMX))
+               return sprintf(buf, "KVM: Mitigation: VMX unsupported\n");
+       else if (!(cr4_read_shadow() & X86_CR4_VMXE))
+               return sprintf(buf, "KVM: Mitigation: VMX disabled\n");
+       else if (itlb_multihit_kvm_mitigation)
                return sprintf(buf, "KVM: Mitigation: Split huge pages\n");
        else
                return sprintf(buf, "KVM: Vulnerable\n");
index af94f05..3112544 100644 (file)
@@ -361,13 +361,6 @@ static void __init ms_hyperv_init_platform(void)
 #endif
 }
 
-void hv_setup_sched_clock(void *sched_clock)
-{
-#ifdef CONFIG_PARAVIRT
-       pv_ops.time.sched_clock = sched_clock;
-#endif
-}
-
 const __initconst struct hypervisor_x86 x86_hyper_ms_hyperv = {
        .name                   = "Microsoft Hyper-V",
        .detect                 = ms_hyperv_platform,
index fd87b59..a8f3af2 100644 (file)
@@ -230,7 +230,7 @@ static int elf_header_exclude_ranges(struct crash_mem *cmem)
        int ret = 0;
 
        /* Exclude the low 1M because it is always reserved */
-       ret = crash_exclude_mem_range(cmem, 0, 1<<20);
+       ret = crash_exclude_mem_range(cmem, 0, (1<<20)-1);
        if (ret)
                return ret;
 
index 7a2bf88..038e19c 100644 (file)
@@ -611,6 +611,10 @@ static void check_xstate_against_struct(int nr)
  * This essentially double-checks what the cpu told us about
  * how large the XSAVE buffer needs to be.  We are recalculating
  * it to be safe.
+ *
+ * Dynamic XSAVE features allocate their own buffers and are not
+ * covered by these checks. Only the size of the buffer for task->fpu
+ * is checked here.
  */
 static void do_extra_xstate_size_checks(void)
 {
@@ -673,6 +677,33 @@ static unsigned int __init get_xsaves_size(void)
        return ebx;
 }
 
+/*
+ * Get the total size of the enabled xstates without the dynamic supervisor
+ * features.
+ */
+static unsigned int __init get_xsaves_size_no_dynamic(void)
+{
+       u64 mask = xfeatures_mask_dynamic();
+       unsigned int size;
+
+       if (!mask)
+               return get_xsaves_size();
+
+       /* Disable dynamic features. */
+       wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor());
+
+       /*
+        * Ask the hardware what size is required of the buffer.
+        * This is the size required for the task->fpu buffer.
+        */
+       size = get_xsaves_size();
+
+       /* Re-enable dynamic features so XSAVES will work on them again. */
+       wrmsrl(MSR_IA32_XSS, xfeatures_mask_supervisor() | mask);
+
+       return size;
+}
+
 static unsigned int __init get_xsave_size(void)
 {
        unsigned int eax, ebx, ecx, edx;
@@ -710,7 +741,7 @@ static int __init init_xstate_size(void)
        xsave_size = get_xsave_size();
 
        if (boot_cpu_has(X86_FEATURE_XSAVES))
-               possible_xstate_size = get_xsaves_size();
+               possible_xstate_size = get_xsaves_size_no_dynamic();
        else
                possible_xstate_size = xsave_size;
 
index f66a6b9..7ed84c2 100644 (file)
@@ -134,38 +134,7 @@ SYM_CODE_START(startup_32)
        movl %eax,pa(initial_page_table+0xffc)
 #endif
 
-#ifdef CONFIG_PARAVIRT
-       /* This is can only trip for a broken bootloader... */
-       cmpw $0x207, pa(boot_params + BP_version)
-       jb .Ldefault_entry
-
-       /* Paravirt-compatible boot parameters.  Look to see what architecture
-               we're booting under. */
-       movl pa(boot_params + BP_hardware_subarch), %eax
-       cmpl $num_subarch_entries, %eax
-       jae .Lbad_subarch
-
-       movl pa(subarch_entries)(,%eax,4), %eax
-       subl $__PAGE_OFFSET, %eax
-       jmp *%eax
-
-.Lbad_subarch:
-SYM_INNER_LABEL_ALIGN(xen_entry, SYM_L_WEAK)
-       /* Unknown implementation; there's really
-          nothing we can do at this point. */
-       ud2a
-
-       __INITDATA
-
-subarch_entries:
-       .long .Ldefault_entry           /* normal x86/PC */
-       .long xen_entry                 /* Xen hypervisor */
-       .long .Ldefault_entry           /* Moorestown MID */
-num_subarch_entries = (. - subarch_entries) / 4
-.previous
-#else
        jmp .Ldefault_entry
-#endif /* CONFIG_PARAVIRT */
 SYM_CODE_END(startup_32)
 
 #ifdef CONFIG_HOTPLUG_CPU
index d6f9467..9afefe3 100644 (file)
@@ -390,7 +390,7 @@ unsigned long x86_fsgsbase_read_task(struct task_struct *task,
                 */
                mutex_lock(&task->mm->context.lock);
                ldt = task->mm->context.ldt;
-               if (unlikely(idx >= ldt->nr_entries))
+               if (unlikely(!ldt || idx >= ldt->nr_entries))
                        base = 0;
                else
                        base = get_desc_base(ldt->entries + idx);
index 46c72f2..6555a85 100644 (file)
@@ -134,10 +134,15 @@ static const struct freq_desc freq_desc_ann = {
        .mask = 0x0f,
 };
 
-/* 24 MHz crystal? : 24 * 13 / 4 = 78 MHz */
+/*
+ * 24 MHz crystal? : 24 * 13 / 4 = 78 MHz
+ * Frequency step for Lightning Mountain SoC is fixed to 78 MHz,
+ * so all the frequency entries are 78000.
+ */
 static const struct freq_desc freq_desc_lgm = {
        .use_msr_plat = true,
-       .freqs = { 78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000 },
+       .freqs = { 78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000,
+                  78000, 78000, 78000, 78000, 78000, 78000, 78000, 78000 },
        .mask = 0x0f,
 };
 
index 183ac60..95ea17a 100644 (file)
@@ -32,7 +32,7 @@ KCOV_INSTRUMENT := n
 # make up the standalone purgatory.ro
 
 PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel
-PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss
+PURGATORY_CFLAGS := -mcmodel=large -ffreestanding -fno-zero-initialized-in-bss -g0
 PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING
 PURGATORY_CFLAGS += -fno-stack-protector
 
@@ -64,6 +64,9 @@ CFLAGS_sha256.o                       += $(PURGATORY_CFLAGS)
 CFLAGS_REMOVE_string.o         += $(PURGATORY_CFLAGS_REMOVE)
 CFLAGS_string.o                        += $(PURGATORY_CFLAGS)
 
+AFLAGS_REMOVE_setup-x86_$(BITS).o      += -Wa,-gdwarf-2
+AFLAGS_REMOVE_entry64.o                        += -Wa,-gdwarf-2
+
 $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
                $(call if_changed,ld)
 
index 1aded63..218acbd 100644 (file)
@@ -19,6 +19,7 @@ config XEN_PV
        bool "Xen PV guest support"
        default y
        depends on XEN
+       depends on X86_64
        select PARAVIRT_XXL
        select XEN_HAVE_PVMMU
        select XEN_HAVE_VPMU
@@ -50,7 +51,7 @@ config XEN_PVHVM_SMP
 
 config XEN_512GB
        bool "Limit Xen pv-domain memory to 512GB"
-       depends on XEN_PV && X86_64
+       depends on XEN_PV
        default y
        help
          Limit paravirtualized user domains to 512GB of RAM.
index 5f1db52..fc5c5ba 100644 (file)
@@ -1,5 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
-OBJECT_FILES_NON_STANDARD_xen-asm_$(BITS).o := y
+OBJECT_FILES_NON_STANDARD_xen-asm.o := y
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not profile debug and lowlevel utilities
@@ -33,7 +33,6 @@ obj-$(CONFIG_XEN_PV)          += mmu_pv.o
 obj-$(CONFIG_XEN_PV)           += irq.o
 obj-$(CONFIG_XEN_PV)           += multicalls.o
 obj-$(CONFIG_XEN_PV)           += xen-asm.o
-obj-$(CONFIG_XEN_PV)           += xen-asm_$(BITS).o
 
 obj-$(CONFIG_XEN_PVH)          += enlighten_pvh.o
 
index 1aff4ae..e82fd19 100644 (file)
@@ -60,10 +60,6 @@ static u32 xen_apic_read(u32 reg)
 
        if (reg == APIC_LVR)
                return 0x14;
-#ifdef CONFIG_X86_32
-       if (reg == APIC_LDR)
-               return SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
-#endif
        if (reg != APIC_ID)
                return 0;
 
@@ -129,14 +125,6 @@ static int xen_phys_pkg_id(int initial_apic_id, int index_msb)
        return initial_apic_id >> index_msb;
 }
 
-#ifdef CONFIG_X86_32
-static int xen_x86_32_early_logical_apicid(int cpu)
-{
-       /* Match with APIC_LDR read. Otherwise setup_local_APIC complains. */
-       return 1 << cpu;
-}
-#endif
-
 static void xen_noop(void)
 {
 }
@@ -199,11 +187,6 @@ static struct apic xen_pv_apic = {
        .icr_write                      = xen_apic_icr_write,
        .wait_icr_idle                  = xen_noop,
        .safe_wait_icr_idle             = xen_safe_apic_wait_icr_idle,
-
-#ifdef CONFIG_X86_32
-       /* generic_processor_info and setup_local_APIC. */
-       .x86_32_early_logical_apicid    = xen_x86_32_early_logical_apicid,
-#endif
 };
 
 static void __init xen_apic_check(void)
index 2aab43a..22e741e 100644 (file)
@@ -119,14 +119,6 @@ static void __init xen_banner(void)
        printk(KERN_INFO "Xen version: %d.%d%s%s\n",
               version >> 16, version & 0xffff, extra.extraversion,
               xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
-
-#ifdef CONFIG_X86_32
-       pr_warn("WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!\n"
-               "Support for running as 32-bit PV-guest under Xen will soon be removed\n"
-               "from the Linux kernel!\n"
-               "Please use either a 64-bit kernel or switch to HVM or PVH mode!\n"
-               "WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!\n");
-#endif
 }
 
 static void __init xen_pv_init_platform(void)
@@ -353,15 +345,13 @@ static void set_aliased_prot(void *v, pgprot_t prot)
        pte_t *ptep;
        pte_t pte;
        unsigned long pfn;
-       struct page *page;
        unsigned char dummy;
+       void *va;
 
        ptep = lookup_address((unsigned long)v, &level);
        BUG_ON(ptep == NULL);
 
        pfn = pte_pfn(*ptep);
-       page = pfn_to_page(pfn);
-
        pte = pfn_pte(pfn, prot);
 
        /*
@@ -391,14 +381,10 @@ static void set_aliased_prot(void *v, pgprot_t prot)
        if (HYPERVISOR_update_va_mapping((unsigned long)v, pte, 0))
                BUG();
 
-       if (!PageHighMem(page)) {
-               void *av = __va(PFN_PHYS(pfn));
+       va = __va(PFN_PHYS(pfn));
 
-               if (av != v)
-                       if (HYPERVISOR_update_va_mapping((unsigned long)av, pte, 0))
-                               BUG();
-       } else
-               kmap_flush_unused();
+       if (va != v && HYPERVISOR_update_va_mapping((unsigned long)va, pte, 0))
+               BUG();
 
        preempt_enable();
 }
@@ -538,30 +524,12 @@ static void load_TLS_descriptor(struct thread_struct *t,
 static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
 {
        /*
-        * XXX sleazy hack: If we're being called in a lazy-cpu zone
-        * and lazy gs handling is enabled, it means we're in a
-        * context switch, and %gs has just been saved.  This means we
-        * can zero it out to prevent faults on exit from the
-        * hypervisor if the next process has no %gs.  Either way, it
-        * has been saved, and the new value will get loaded properly.
-        * This will go away as soon as Xen has been modified to not
-        * save/restore %gs for normal hypercalls.
-        *
-        * On x86_64, this hack is not used for %gs, because gs points
-        * to KERNEL_GS_BASE (and uses it for PDA references), so we
-        * must not zero %gs on x86_64
-        *
-        * For x86_64, we need to zero %fs, otherwise we may get an
+        * In lazy mode we need to zero %fs, otherwise we may get an
         * exception between the new %fs descriptor being loaded and
         * %fs being effectively cleared at __switch_to().
         */
-       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU) {
-#ifdef CONFIG_X86_32
-               lazy_load_gs(0);
-#else
+       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)
                loadsegment(fs, 0);
-#endif
-       }
 
        xen_mc_batch();
 
@@ -572,13 +540,11 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
        xen_mc_issue(PARAVIRT_LAZY_CPU);
 }
 
-#ifdef CONFIG_X86_64
 static void xen_load_gs_index(unsigned int idx)
 {
        if (HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, idx))
                BUG();
 }
-#endif
 
 static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
                                const void *ptr)
@@ -597,7 +563,6 @@ static void xen_write_ldt_entry(struct desc_struct *dt, int entrynum,
        preempt_enable();
 }
 
-#ifdef CONFIG_X86_64
 void noist_exc_debug(struct pt_regs *regs);
 
 DEFINE_IDTENTRY_RAW(xenpv_exc_nmi)
@@ -697,7 +662,6 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist)
 
        return true;
 }
-#endif
 
 static int cvt_gate_to_trap(int vector, const gate_desc *val,
                            struct trap_info *info)
@@ -710,10 +674,8 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val,
        info->vector = vector;
 
        addr = gate_offset(val);
-#ifdef CONFIG_X86_64
        if (!get_trap_addr((void **)&addr, val->bits.ist))
                return 0;
-#endif /* CONFIG_X86_64 */
        info->address = addr;
 
        info->cs = gate_segment(val);
@@ -958,15 +920,12 @@ static u64 xen_read_msr_safe(unsigned int msr, int *err)
 static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
 {
        int ret;
-#ifdef CONFIG_X86_64
        unsigned int which;
        u64 base;
-#endif
 
        ret = 0;
 
        switch (msr) {
-#ifdef CONFIG_X86_64
        case MSR_FS_BASE:               which = SEGBASE_FS; goto set;
        case MSR_KERNEL_GS_BASE:        which = SEGBASE_GS_USER; goto set;
        case MSR_GS_BASE:               which = SEGBASE_GS_KERNEL; goto set;
@@ -976,7 +935,6 @@ static int xen_write_msr_safe(unsigned int msr, unsigned low, unsigned high)
                if (HYPERVISOR_set_segment_base(which, base) != 0)
                        ret = -EIO;
                break;
-#endif
 
        case MSR_STAR:
        case MSR_CSTAR:
@@ -1058,9 +1016,7 @@ void __init xen_setup_vcpu_info_placement(void)
 static const struct pv_info xen_info __initconst = {
        .shared_kernel_pmd = 0,
 
-#ifdef CONFIG_X86_64
        .extra_user_64bit_cs = FLAT_USER_CS64,
-#endif
        .name = "Xen",
 };
 
@@ -1086,18 +1042,14 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
        .read_pmc = xen_read_pmc,
 
        .iret = xen_iret,
-#ifdef CONFIG_X86_64
        .usergs_sysret64 = xen_sysret64,
-#endif
 
        .load_tr_desc = paravirt_nop,
        .set_ldt = xen_set_ldt,
        .load_gdt = xen_load_gdt,
        .load_idt = xen_load_idt,
        .load_tls = xen_load_tls,
-#ifdef CONFIG_X86_64
        .load_gs_index = xen_load_gs_index,
-#endif
 
        .alloc_ldt = xen_alloc_ldt,
        .free_ldt = xen_free_ldt,
@@ -1364,15 +1316,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 
        /* keep using Xen gdt for now; no urgent need to change it */
 
-#ifdef CONFIG_X86_32
-       pv_info.kernel_rpl = 1;
-       if (xen_feature(XENFEAT_supervisor_mode_kernel))
-               pv_info.kernel_rpl = 0;
-#else
        pv_info.kernel_rpl = 0;
-#endif
-       /* set the limit of our address space */
-       xen_reserve_top();
 
        /*
         * We used to do this in xen_arch_setup, but that is too late
@@ -1384,12 +1328,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
        if (rc != 0)
                xen_raw_printk("physdev_op failed %d\n", rc);
 
-#ifdef CONFIG_X86_32
-       /* set up basic CPUID stuff */
-       cpu_detect(&new_cpu_data);
-       set_cpu_cap(&new_cpu_data, X86_FEATURE_FPU);
-       new_cpu_data.x86_capability[CPUID_1_EDX] = cpuid_edx(1);
-#endif
 
        if (xen_start_info->mod_start) {
            if (xen_start_info->flags & SIF_MOD_START_PFN)
@@ -1458,12 +1396,8 @@ asmlinkage __visible void __init xen_start_kernel(void)
        xen_efi_init(&boot_params);
 
        /* Start the world */
-#ifdef CONFIG_X86_32
-       i386_start_kernel();
-#else
        cr4_init_shadow(); /* 32b kernel does this in i386_start_kernel() */
        x86_64_start_reservations((char *)__pa_symbol(&boot_params));
-#endif
 }
 
 static int xen_cpu_up_prepare_pv(unsigned int cpu)
index a58d9c6..3273c98 100644 (file)
 #include "mmu.h"
 #include "debugfs.h"
 
-#ifdef CONFIG_X86_32
-/*
- * Identity map, in addition to plain kernel map.  This needs to be
- * large enough to allocate page table pages to allocate the rest.
- * Each page can map 2MB.
- */
-#define LEVEL1_IDENT_ENTRIES   (PTRS_PER_PTE * 4)
-static RESERVE_BRK_ARRAY(pte_t, level1_ident_pgt, LEVEL1_IDENT_ENTRIES);
-#endif
-#ifdef CONFIG_X86_64
 /* l3 pud for userspace vsyscall mapping */
 static pud_t level3_user_vsyscall[PTRS_PER_PUD] __page_aligned_bss;
-#endif /* CONFIG_X86_64 */
 
 /*
  * Protects atomic reservation decrease/increase against concurrent increases.
@@ -280,10 +269,7 @@ static inline void __xen_set_pte(pte_t *ptep, pte_t pteval)
        if (!xen_batched_set_pte(ptep, pteval)) {
                /*
                 * Could call native_set_pte() here and trap and
-                * emulate the PTE write but with 32-bit guests this
-                * needs two traps (one for each of the two 32-bit
-                * words in the PTE) so do one hypercall directly
-                * instead.
+                * emulate the PTE write, but a hypercall is much cheaper.
                 */
                struct mmu_update u;
 
@@ -439,26 +425,6 @@ static void xen_set_pud(pud_t *ptr, pud_t val)
        xen_set_pud_hyper(ptr, val);
 }
 
-#ifdef CONFIG_X86_PAE
-static void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
-{
-       trace_xen_mmu_set_pte_atomic(ptep, pte);
-       __xen_set_pte(ptep, pte);
-}
-
-static void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
-{
-       trace_xen_mmu_pte_clear(mm, addr, ptep);
-       __xen_set_pte(ptep, native_make_pte(0));
-}
-
-static void xen_pmd_clear(pmd_t *pmdp)
-{
-       trace_xen_mmu_pmd_clear(pmdp);
-       set_pmd(pmdp, __pmd(0));
-}
-#endif /* CONFIG_X86_PAE */
-
 __visible pmd_t xen_make_pmd(pmdval_t pmd)
 {
        pmd = pte_pfn_to_mfn(pmd);
@@ -466,7 +432,6 @@ __visible pmd_t xen_make_pmd(pmdval_t pmd)
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_make_pmd);
 
-#ifdef CONFIG_X86_64
 __visible pudval_t xen_pud_val(pud_t pud)
 {
        return pte_mfn_to_pfn(pud.pud);
@@ -571,27 +536,27 @@ __visible p4d_t xen_make_p4d(p4dval_t p4d)
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_make_p4d);
 #endif  /* CONFIG_PGTABLE_LEVELS >= 5 */
-#endif /* CONFIG_X86_64 */
 
-static int xen_pmd_walk(struct mm_struct *mm, pmd_t *pmd,
-               int (*func)(struct mm_struct *mm, struct page *, enum pt_level),
-               bool last, unsigned long limit)
+static void xen_pmd_walk(struct mm_struct *mm, pmd_t *pmd,
+                        void (*func)(struct mm_struct *mm, struct page *,
+                                     enum pt_level),
+                        bool last, unsigned long limit)
 {
-       int i, nr, flush = 0;
+       int i, nr;
 
        nr = last ? pmd_index(limit) + 1 : PTRS_PER_PMD;
        for (i = 0; i < nr; i++) {
                if (!pmd_none(pmd[i]))
-                       flush |= (*func)(mm, pmd_page(pmd[i]), PT_PTE);
+                       (*func)(mm, pmd_page(pmd[i]), PT_PTE);
        }
-       return flush;
 }
 
-static int xen_pud_walk(struct mm_struct *mm, pud_t *pud,
-               int (*func)(struct mm_struct *mm, struct page *, enum pt_level),
-               bool last, unsigned long limit)
+static void xen_pud_walk(struct mm_struct *mm, pud_t *pud,
+                        void (*func)(struct mm_struct *mm, struct page *,
+                                     enum pt_level),
+                        bool last, unsigned long limit)
 {
-       int i, nr, flush = 0;
+       int i, nr;
 
        nr = last ? pud_index(limit) + 1 : PTRS_PER_PUD;
        for (i = 0; i < nr; i++) {
@@ -602,29 +567,26 @@ static int xen_pud_walk(struct mm_struct *mm, pud_t *pud,
 
                pmd = pmd_offset(&pud[i], 0);
                if (PTRS_PER_PMD > 1)
-                       flush |= (*func)(mm, virt_to_page(pmd), PT_PMD);
-               flush |= xen_pmd_walk(mm, pmd, func,
-                               last && i == nr - 1, limit);
+                       (*func)(mm, virt_to_page(pmd), PT_PMD);
+               xen_pmd_walk(mm, pmd, func, last && i == nr - 1, limit);
        }
-       return flush;
 }
 
-static int xen_p4d_walk(struct mm_struct *mm, p4d_t *p4d,
-               int (*func)(struct mm_struct *mm, struct page *, enum pt_level),
-               bool last, unsigned long limit)
+static void xen_p4d_walk(struct mm_struct *mm, p4d_t *p4d,
+                        void (*func)(struct mm_struct *mm, struct page *,
+                                     enum pt_level),
+                        bool last, unsigned long limit)
 {
-       int flush = 0;
        pud_t *pud;
 
 
        if (p4d_none(*p4d))
-               return flush;
+               return;
 
        pud = pud_offset(p4d, 0);
        if (PTRS_PER_PUD > 1)
-               flush |= (*func)(mm, virt_to_page(pud), PT_PUD);
-       flush |= xen_pud_walk(mm, pud, func, last, limit);
-       return flush;
+               (*func)(mm, virt_to_page(pud), PT_PUD);
+       xen_pud_walk(mm, pud, func, last, limit);
 }
 
 /*
@@ -636,32 +598,27 @@ static int xen_p4d_walk(struct mm_struct *mm, p4d_t *p4d,
  * will be STACK_TOP_MAX, but at boot we need to pin up to
  * FIXADDR_TOP.
  *
- * For 32-bit the important bit is that we don't pin beyond there,
- * because then we start getting into Xen's ptes.
- *
- * For 64-bit, we must skip the Xen hole in the middle of the address
- * space, just after the big x86-64 virtual hole.
+ * We must skip the Xen hole in the middle of the address space, just after
+ * the big x86-64 virtual hole.
  */
-static int __xen_pgd_walk(struct mm_struct *mm, pgd_t *pgd,
-                         int (*func)(struct mm_struct *mm, struct page *,
-                                     enum pt_level),
-                         unsigned long limit)
+static void __xen_pgd_walk(struct mm_struct *mm, pgd_t *pgd,
+                          void (*func)(struct mm_struct *mm, struct page *,
+                                       enum pt_level),
+                          unsigned long limit)
 {
-       int i, nr, flush = 0;
+       int i, nr;
        unsigned hole_low = 0, hole_high = 0;
 
        /* The limit is the last byte to be touched */
        limit--;
        BUG_ON(limit >= FIXADDR_TOP);
 
-#ifdef CONFIG_X86_64
        /*
         * 64-bit has a great big hole in the middle of the address
         * space, which contains the Xen mappings.
         */
        hole_low = pgd_index(GUARD_HOLE_BASE_ADDR);
        hole_high = pgd_index(GUARD_HOLE_END_ADDR);
-#endif
 
        nr = pgd_index(limit) + 1;
        for (i = 0; i < nr; i++) {
@@ -674,22 +631,20 @@ static int __xen_pgd_walk(struct mm_struct *mm, pgd_t *pgd,
                        continue;
 
                p4d = p4d_offset(&pgd[i], 0);
-               flush |= xen_p4d_walk(mm, p4d, func, i == nr - 1, limit);
+               xen_p4d_walk(mm, p4d, func, i == nr - 1, limit);
        }
 
        /* Do the top level last, so that the callbacks can use it as
           a cue to do final things like tlb flushes. */
-       flush |= (*func)(mm, virt_to_page(pgd), PT_PGD);
-
-       return flush;
+       (*func)(mm, virt_to_page(pgd), PT_PGD);
 }
 
-static int xen_pgd_walk(struct mm_struct *mm,
-                       int (*func)(struct mm_struct *mm, struct page *,
-                                   enum pt_level),
-                       unsigned long limit)
+static void xen_pgd_walk(struct mm_struct *mm,
+                        void (*func)(struct mm_struct *mm, struct page *,
+                                     enum pt_level),
+                        unsigned long limit)
 {
-       return __xen_pgd_walk(mm, mm->pgd, func, limit);
+       __xen_pgd_walk(mm, mm->pgd, func, limit);
 }
 
 /* If we're using split pte locks, then take the page's lock and
@@ -722,26 +677,17 @@ static void xen_do_pin(unsigned level, unsigned long pfn)
        xen_extend_mmuext_op(&op);
 }
 
-static int xen_pin_page(struct mm_struct *mm, struct page *page,
-                       enum pt_level level)
+static void xen_pin_page(struct mm_struct *mm, struct page *page,
+                        enum pt_level level)
 {
        unsigned pgfl = TestSetPagePinned(page);
-       int flush;
-
-       if (pgfl)
-               flush = 0;              /* already pinned */
-       else if (PageHighMem(page))
-               /* kmaps need flushing if we found an unpinned
-                  highpage */
-               flush = 1;
-       else {
+
+       if (!pgfl) {
                void *pt = lowmem_page_address(page);
                unsigned long pfn = page_to_pfn(page);
                struct multicall_space mcs = __xen_mc_entry(0);
                spinlock_t *ptl;
 
-               flush = 0;
-
                /*
                 * We need to hold the pagetable lock between the time
                 * we make the pagetable RO and when we actually pin
@@ -778,8 +724,6 @@ static int xen_pin_page(struct mm_struct *mm, struct page *page,
                        xen_mc_callback(xen_pte_unlock, ptl);
                }
        }
-
-       return flush;
 }
 
 /* This is called just after a mm has been created, but it has not
@@ -787,39 +731,22 @@ static int xen_pin_page(struct mm_struct *mm, struct page *page,
    read-only, and can be pinned. */
 static void __xen_pgd_pin(struct mm_struct *mm, pgd_t *pgd)
 {
+       pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
        trace_xen_mmu_pgd_pin(mm, pgd);
 
        xen_mc_batch();
 
-       if (__xen_pgd_walk(mm, pgd, xen_pin_page, USER_LIMIT)) {
-               /* re-enable interrupts for flushing */
-               xen_mc_issue(0);
+       __xen_pgd_walk(mm, pgd, xen_pin_page, USER_LIMIT);
 
-               kmap_flush_unused();
+       xen_do_pin(MMUEXT_PIN_L4_TABLE, PFN_DOWN(__pa(pgd)));
 
-               xen_mc_batch();
+       if (user_pgd) {
+               xen_pin_page(mm, virt_to_page(user_pgd), PT_PGD);
+               xen_do_pin(MMUEXT_PIN_L4_TABLE,
+                          PFN_DOWN(__pa(user_pgd)));
        }
 
-#ifdef CONFIG_X86_64
-       {
-               pgd_t *user_pgd = xen_get_user_pgd(pgd);
-
-               xen_do_pin(MMUEXT_PIN_L4_TABLE, PFN_DOWN(__pa(pgd)));
-
-               if (user_pgd) {
-                       xen_pin_page(mm, virt_to_page(user_pgd), PT_PGD);
-                       xen_do_pin(MMUEXT_PIN_L4_TABLE,
-                                  PFN_DOWN(__pa(user_pgd)));
-               }
-       }
-#else /* CONFIG_X86_32 */
-#ifdef CONFIG_X86_PAE
-       /* Need to make sure unshared kernel PMD is pinnable */
-       xen_pin_page(mm, pgd_page(pgd[pgd_index(TASK_SIZE)]),
-                    PT_PMD);
-#endif
-       xen_do_pin(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(pgd)));
-#endif /* CONFIG_X86_64 */
        xen_mc_issue(0);
 }
 
@@ -854,11 +781,10 @@ void xen_mm_pin_all(void)
        spin_unlock(&pgd_lock);
 }
 
-static int __init xen_mark_pinned(struct mm_struct *mm, struct page *page,
-                                 enum pt_level level)
+static void __init xen_mark_pinned(struct mm_struct *mm, struct page *page,
+                                  enum pt_level level)
 {
        SetPagePinned(page);
-       return 0;
 }
 
 /*
@@ -870,18 +796,16 @@ static int __init xen_mark_pinned(struct mm_struct *mm, struct page *page,
 static void __init xen_after_bootmem(void)
 {
        static_branch_enable(&xen_struct_pages_ready);
-#ifdef CONFIG_X86_64
        SetPagePinned(virt_to_page(level3_user_vsyscall));
-#endif
        xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP);
 }
 
-static int xen_unpin_page(struct mm_struct *mm, struct page *page,
-                         enum pt_level level)
+static void xen_unpin_page(struct mm_struct *mm, struct page *page,
+                          enum pt_level level)
 {
        unsigned pgfl = TestClearPagePinned(page);
 
-       if (pgfl && !PageHighMem(page)) {
+       if (pgfl) {
                void *pt = lowmem_page_address(page);
                unsigned long pfn = page_to_pfn(page);
                spinlock_t *ptl = NULL;
@@ -912,36 +836,24 @@ static int xen_unpin_page(struct mm_struct *mm, struct page *page,
                        xen_mc_callback(xen_pte_unlock, ptl);
                }
        }
-
-       return 0;               /* never need to flush on unpin */
 }
 
 /* Release a pagetables pages back as normal RW */
 static void __xen_pgd_unpin(struct mm_struct *mm, pgd_t *pgd)
 {
+       pgd_t *user_pgd = xen_get_user_pgd(pgd);
+
        trace_xen_mmu_pgd_unpin(mm, pgd);
 
        xen_mc_batch();
 
        xen_do_pin(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
 
-#ifdef CONFIG_X86_64
-       {
-               pgd_t *user_pgd = xen_get_user_pgd(pgd);
-
-               if (user_pgd) {
-                       xen_do_pin(MMUEXT_UNPIN_TABLE,
-                                  PFN_DOWN(__pa(user_pgd)));
-                       xen_unpin_page(mm, virt_to_page(user_pgd), PT_PGD);
-               }
+       if (user_pgd) {
+               xen_do_pin(MMUEXT_UNPIN_TABLE,
+                          PFN_DOWN(__pa(user_pgd)));
+               xen_unpin_page(mm, virt_to_page(user_pgd), PT_PGD);
        }
-#endif
-
-#ifdef CONFIG_X86_PAE
-       /* Need to make sure unshared kernel PMD is unpinned */
-       xen_unpin_page(mm, pgd_page(pgd[pgd_index(TASK_SIZE)]),
-                      PT_PMD);
-#endif
 
        __xen_pgd_walk(mm, pgd, xen_unpin_page, USER_LIMIT);
 
@@ -1089,7 +1001,6 @@ static void __init pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
                BUG();
 }
 
-#ifdef CONFIG_X86_64
 static void __init xen_cleanhighmap(unsigned long vaddr,
                                    unsigned long vaddr_end)
 {
@@ -1273,17 +1184,15 @@ static void __init xen_pagetable_cleanhighmap(void)
        xen_cleanhighmap(addr, roundup(addr + size, PMD_SIZE * 2));
        xen_start_info->pt_base = (unsigned long)__va(__pa(xen_start_info->pt_base));
 }
-#endif
 
 static void __init xen_pagetable_p2m_setup(void)
 {
        xen_vmalloc_p2m_tree();
 
-#ifdef CONFIG_X86_64
        xen_pagetable_p2m_free();
 
        xen_pagetable_cleanhighmap();
-#endif
+
        /* And revector! Bye bye old array */
        xen_start_info->mfn_list = (unsigned long)xen_p2m_addr;
 }
@@ -1420,6 +1329,8 @@ static void __xen_write_cr3(bool kernel, unsigned long cr3)
 }
 static void xen_write_cr3(unsigned long cr3)
 {
+       pgd_t *user_pgd = xen_get_user_pgd(__va(cr3));
+
        BUG_ON(preemptible());
 
        xen_mc_batch();  /* disables interrupts */
@@ -1430,20 +1341,14 @@ static void xen_write_cr3(unsigned long cr3)
 
        __xen_write_cr3(true, cr3);
 
-#ifdef CONFIG_X86_64
-       {
-               pgd_t *user_pgd = xen_get_user_pgd(__va(cr3));
-               if (user_pgd)
-                       __xen_write_cr3(false, __pa(user_pgd));
-               else
-                       __xen_write_cr3(false, 0);
-       }
-#endif
+       if (user_pgd)
+               __xen_write_cr3(false, __pa(user_pgd));
+       else
+               __xen_write_cr3(false, 0);
 
        xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */
 }
 
-#ifdef CONFIG_X86_64
 /*
  * At the start of the day - when Xen launches a guest, it has already
  * built pagetables for the guest. We diligently look over them
@@ -1478,49 +1383,39 @@ static void __init xen_write_cr3_init(unsigned long cr3)
 
        xen_mc_issue(PARAVIRT_LAZY_CPU);  /* interrupts restored */
 }
-#endif
 
 static int xen_pgd_alloc(struct mm_struct *mm)
 {
        pgd_t *pgd = mm->pgd;
-       int ret = 0;
+       struct page *page = virt_to_page(pgd);
+       pgd_t *user_pgd;
+       int ret = -ENOMEM;
 
        BUG_ON(PagePinned(virt_to_page(pgd)));
+       BUG_ON(page->private != 0);
 
-#ifdef CONFIG_X86_64
-       {
-               struct page *page = virt_to_page(pgd);
-               pgd_t *user_pgd;
+       user_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
+       page->private = (unsigned long)user_pgd;
 
-               BUG_ON(page->private != 0);
-
-               ret = -ENOMEM;
-
-               user_pgd = (pgd_t *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-               page->private = (unsigned long)user_pgd;
-
-               if (user_pgd != NULL) {
+       if (user_pgd != NULL) {
 #ifdef CONFIG_X86_VSYSCALL_EMULATION
-                       user_pgd[pgd_index(VSYSCALL_ADDR)] =
-                               __pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
+               user_pgd[pgd_index(VSYSCALL_ADDR)] =
+                       __pgd(__pa(level3_user_vsyscall) | _PAGE_TABLE);
 #endif
-                       ret = 0;
-               }
-
-               BUG_ON(PagePinned(virt_to_page(xen_get_user_pgd(pgd))));
+               ret = 0;
        }
-#endif
+
+       BUG_ON(PagePinned(virt_to_page(xen_get_user_pgd(pgd))));
+
        return ret;
 }
 
 static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
 {
-#ifdef CONFIG_X86_64
        pgd_t *user_pgd = xen_get_user_pgd(pgd);
 
        if (user_pgd)
                free_page((unsigned long)user_pgd);
-#endif
 }
 
 /*
@@ -1539,7 +1434,6 @@ static void xen_pgd_free(struct mm_struct *mm, pgd_t *pgd)
  */
 __visible pte_t xen_make_pte_init(pteval_t pte)
 {
-#ifdef CONFIG_X86_64
        unsigned long pfn;
 
        /*
@@ -1553,7 +1447,7 @@ __visible pte_t xen_make_pte_init(pteval_t pte)
            pfn >= xen_start_info->first_p2m_pfn &&
            pfn < xen_start_info->first_p2m_pfn + xen_start_info->nr_p2m_frames)
                pte &= ~_PAGE_RW;
-#endif
+
        pte = pte_pfn_to_mfn(pte);
        return native_make_pte(pte);
 }
@@ -1561,13 +1455,6 @@ PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte_init);
 
 static void __init xen_set_pte_init(pte_t *ptep, pte_t pte)
 {
-#ifdef CONFIG_X86_32
-       /* If there's an existing pte, then don't allow _PAGE_RW to be set */
-       if (pte_mfn(pte) != INVALID_P2M_ENTRY
-           && pte_val_ma(*ptep) & _PAGE_PRESENT)
-               pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
-                              pte_val_ma(pte));
-#endif
        __xen_set_pte(ptep, pte);
 }
 
@@ -1642,20 +1529,14 @@ static inline void xen_alloc_ptpage(struct mm_struct *mm, unsigned long pfn,
                if (static_branch_likely(&xen_struct_pages_ready))
                        SetPagePinned(page);
 
-               if (!PageHighMem(page)) {
-                       xen_mc_batch();
+               xen_mc_batch();
 
-                       __set_pfn_prot(pfn, PAGE_KERNEL_RO);
+               __set_pfn_prot(pfn, PAGE_KERNEL_RO);
 
-                       if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS)
-                               __pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
+               if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS)
+                       __pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
 
-                       xen_mc_issue(PARAVIRT_LAZY_MMU);
-               } else {
-                       /* make sure there are no stray mappings of
-                          this page */
-                       kmap_flush_unused();
-               }
+               xen_mc_issue(PARAVIRT_LAZY_MMU);
        }
 }
 
@@ -1678,16 +1559,15 @@ static inline void xen_release_ptpage(unsigned long pfn, unsigned level)
        trace_xen_mmu_release_ptpage(pfn, level, pinned);
 
        if (pinned) {
-               if (!PageHighMem(page)) {
-                       xen_mc_batch();
+               xen_mc_batch();
 
-                       if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS)
-                               __pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
+               if (level == PT_PTE && USE_SPLIT_PTE_PTLOCKS)
+                       __pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
 
-                       __set_pfn_prot(pfn, PAGE_KERNEL);
+               __set_pfn_prot(pfn, PAGE_KERNEL);
+
+               xen_mc_issue(PARAVIRT_LAZY_MMU);
 
-                       xen_mc_issue(PARAVIRT_LAZY_MMU);
-               }
                ClearPagePinned(page);
        }
 }
@@ -1702,7 +1582,6 @@ static void xen_release_pmd(unsigned long pfn)
        xen_release_ptpage(pfn, PT_PMD);
 }
 
-#ifdef CONFIG_X86_64
 static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn)
 {
        xen_alloc_ptpage(mm, pfn, PT_PUD);
@@ -1712,20 +1591,6 @@ static void xen_release_pud(unsigned long pfn)
 {
        xen_release_ptpage(pfn, PT_PUD);
 }
-#endif
-
-void __init xen_reserve_top(void)
-{
-#ifdef CONFIG_X86_32
-       unsigned long top = HYPERVISOR_VIRT_START;
-       struct xen_platform_parameters pp;
-
-       if (HYPERVISOR_xen_version(XENVER_platform_parameters, &pp) == 0)
-               top = pp.virt_start;
-
-       reserve_top_address(-top);
-#endif /* CONFIG_X86_32 */
-}
 
 /*
  * Like __va(), but returns address in the kernel mapping (which is
@@ -1733,11 +1598,7 @@ void __init xen_reserve_top(void)
  */
 static void * __init __ka(phys_addr_t paddr)
 {
-#ifdef CONFIG_X86_64
        return (void *)(paddr + __START_KERNEL_map);
-#else
-       return __va(paddr);
-#endif
 }
 
 /* Convert a machine address to physical address */
@@ -1771,56 +1632,7 @@ static void __init set_page_prot(void *addr, pgprot_t prot)
 {
        return set_page_prot_flags(addr, prot, UVMF_NONE);
 }
-#ifdef CONFIG_X86_32
-static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
-{
-       unsigned pmdidx, pteidx;
-       unsigned ident_pte;
-       unsigned long pfn;
-
-       level1_ident_pgt = extend_brk(sizeof(pte_t) * LEVEL1_IDENT_ENTRIES,
-                                     PAGE_SIZE);
-
-       ident_pte = 0;
-       pfn = 0;
-       for (pmdidx = 0; pmdidx < PTRS_PER_PMD && pfn < max_pfn; pmdidx++) {
-               pte_t *pte_page;
-
-               /* Reuse or allocate a page of ptes */
-               if (pmd_present(pmd[pmdidx]))
-                       pte_page = m2v(pmd[pmdidx].pmd);
-               else {
-                       /* Check for free pte pages */
-                       if (ident_pte == LEVEL1_IDENT_ENTRIES)
-                               break;
-
-                       pte_page = &level1_ident_pgt[ident_pte];
-                       ident_pte += PTRS_PER_PTE;
-
-                       pmd[pmdidx] = __pmd(__pa(pte_page) | _PAGE_TABLE);
-               }
-
-               /* Install mappings */
-               for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) {
-                       pte_t pte;
 
-                       if (pfn > max_pfn_mapped)
-                               max_pfn_mapped = pfn;
-
-                       if (!pte_none(pte_page[pteidx]))
-                               continue;
-
-                       pte = pfn_pte(pfn, PAGE_KERNEL_EXEC);
-                       pte_page[pteidx] = pte;
-               }
-       }
-
-       for (pteidx = 0; pteidx < ident_pte; pteidx += PTRS_PER_PTE)
-               set_page_prot(&level1_ident_pgt[pteidx], PAGE_KERNEL_RO);
-
-       set_page_prot(pmd, PAGE_KERNEL_RO);
-}
-#endif
 void __init xen_setup_machphys_mapping(void)
 {
        struct xen_machphys_mapping mapping;
@@ -1831,13 +1643,8 @@ void __init xen_setup_machphys_mapping(void)
        } else {
                machine_to_phys_nr = MACH2PHYS_NR_ENTRIES;
        }
-#ifdef CONFIG_X86_32
-       WARN_ON((machine_to_phys_mapping + (machine_to_phys_nr - 1))
-               < machine_to_phys_mapping);
-#endif
 }
 
-#ifdef CONFIG_X86_64
 static void __init convert_pfn_mfn(void *v)
 {
        pte_t *pte = v;
@@ -2168,105 +1975,6 @@ void __init xen_relocate_p2m(void)
        xen_start_info->nr_p2m_frames = n_frames;
 }
 
-#else  /* !CONFIG_X86_64 */
-static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD);
-static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD);
-RESERVE_BRK(fixup_kernel_pmd, PAGE_SIZE);
-RESERVE_BRK(fixup_kernel_pte, PAGE_SIZE);
-
-static void __init xen_write_cr3_init(unsigned long cr3)
-{
-       unsigned long pfn = PFN_DOWN(__pa(swapper_pg_dir));
-
-       BUG_ON(read_cr3_pa() != __pa(initial_page_table));
-       BUG_ON(cr3 != __pa(swapper_pg_dir));
-
-       /*
-        * We are switching to swapper_pg_dir for the first time (from
-        * initial_page_table) and therefore need to mark that page
-        * read-only and then pin it.
-        *
-        * Xen disallows sharing of kernel PMDs for PAE
-        * guests. Therefore we must copy the kernel PMD from
-        * initial_page_table into a new kernel PMD to be used in
-        * swapper_pg_dir.
-        */
-       swapper_kernel_pmd =
-               extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
-       copy_page(swapper_kernel_pmd, initial_kernel_pmd);
-       swapper_pg_dir[KERNEL_PGD_BOUNDARY] =
-               __pgd(__pa(swapper_kernel_pmd) | _PAGE_PRESENT);
-       set_page_prot(swapper_kernel_pmd, PAGE_KERNEL_RO);
-
-       set_page_prot(swapper_pg_dir, PAGE_KERNEL_RO);
-       xen_write_cr3(cr3);
-       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, pfn);
-
-       pin_pagetable_pfn(MMUEXT_UNPIN_TABLE,
-                         PFN_DOWN(__pa(initial_page_table)));
-       set_page_prot(initial_page_table, PAGE_KERNEL);
-       set_page_prot(initial_kernel_pmd, PAGE_KERNEL);
-
-       pv_ops.mmu.write_cr3 = &xen_write_cr3;
-}
-
-/*
- * For 32 bit domains xen_start_info->pt_base is the pgd address which might be
- * not the first page table in the page table pool.
- * Iterate through the initial page tables to find the real page table base.
- */
-static phys_addr_t __init xen_find_pt_base(pmd_t *pmd)
-{
-       phys_addr_t pt_base, paddr;
-       unsigned pmdidx;
-
-       pt_base = min(__pa(xen_start_info->pt_base), __pa(pmd));
-
-       for (pmdidx = 0; pmdidx < PTRS_PER_PMD; pmdidx++)
-               if (pmd_present(pmd[pmdidx]) && !pmd_large(pmd[pmdidx])) {
-                       paddr = m2p(pmd[pmdidx].pmd);
-                       pt_base = min(pt_base, paddr);
-               }
-
-       return pt_base;
-}
-
-void __init xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn)
-{
-       pmd_t *kernel_pmd;
-
-       kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
-
-       xen_pt_base = xen_find_pt_base(kernel_pmd);
-       xen_pt_size = xen_start_info->nr_pt_frames * PAGE_SIZE;
-
-       initial_kernel_pmd =
-               extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
-
-       max_pfn_mapped = PFN_DOWN(xen_pt_base + xen_pt_size + 512 * 1024);
-
-       copy_page(initial_kernel_pmd, kernel_pmd);
-
-       xen_map_identity_early(initial_kernel_pmd, max_pfn);
-
-       copy_page(initial_page_table, pgd);
-       initial_page_table[KERNEL_PGD_BOUNDARY] =
-               __pgd(__pa(initial_kernel_pmd) | _PAGE_PRESENT);
-
-       set_page_prot(initial_kernel_pmd, PAGE_KERNEL_RO);
-       set_page_prot(initial_page_table, PAGE_KERNEL_RO);
-       set_page_prot(empty_zero_page, PAGE_KERNEL_RO);
-
-       pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
-
-       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE,
-                         PFN_DOWN(__pa(initial_page_table)));
-       xen_write_cr3(__pa(initial_page_table));
-
-       memblock_reserve(xen_pt_base, xen_pt_size);
-}
-#endif /* CONFIG_X86_64 */
-
 void __init xen_reserve_special_pages(void)
 {
        phys_addr_t paddr;
@@ -2300,12 +2008,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
 
        switch (idx) {
        case FIX_BTMAP_END ... FIX_BTMAP_BEGIN:
-#ifdef CONFIG_X86_32
-       case FIX_WP_TEST:
-# ifdef CONFIG_HIGHMEM
-       case FIX_KMAP_BEGIN ... FIX_KMAP_END:
-# endif
-#elif defined(CONFIG_X86_VSYSCALL_EMULATION)
+#ifdef CONFIG_X86_VSYSCALL_EMULATION
        case VSYSCALL_PAGE:
 #endif
                /* All local page mappings */
@@ -2357,9 +2060,7 @@ static void __init xen_post_allocator_init(void)
        pv_ops.mmu.set_pte = xen_set_pte;
        pv_ops.mmu.set_pmd = xen_set_pmd;
        pv_ops.mmu.set_pud = xen_set_pud;
-#ifdef CONFIG_X86_64
        pv_ops.mmu.set_p4d = xen_set_p4d;
-#endif
 
        /* This will work as long as patching hasn't happened yet
           (which it hasn't) */
@@ -2367,15 +2068,11 @@ static void __init xen_post_allocator_init(void)
        pv_ops.mmu.alloc_pmd = xen_alloc_pmd;
        pv_ops.mmu.release_pte = xen_release_pte;
        pv_ops.mmu.release_pmd = xen_release_pmd;
-#ifdef CONFIG_X86_64
        pv_ops.mmu.alloc_pud = xen_alloc_pud;
        pv_ops.mmu.release_pud = xen_release_pud;
-#endif
        pv_ops.mmu.make_pte = PV_CALLEE_SAVE(xen_make_pte);
 
-#ifdef CONFIG_X86_64
        pv_ops.mmu.write_cr3 = &xen_write_cr3;
-#endif
 }
 
 static void xen_leave_lazy_mmu(void)
@@ -2420,17 +2117,11 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
        .make_pte = PV_CALLEE_SAVE(xen_make_pte_init),
        .make_pgd = PV_CALLEE_SAVE(xen_make_pgd),
 
-#ifdef CONFIG_X86_PAE
-       .set_pte_atomic = xen_set_pte_atomic,
-       .pte_clear = xen_pte_clear,
-       .pmd_clear = xen_pmd_clear,
-#endif /* CONFIG_X86_PAE */
        .set_pud = xen_set_pud_hyper,
 
        .make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
        .pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
 
-#ifdef CONFIG_X86_64
        .pud_val = PV_CALLEE_SAVE(xen_pud_val),
        .make_pud = PV_CALLEE_SAVE(xen_make_pud),
        .set_p4d = xen_set_p4d_hyper,
@@ -2442,7 +2133,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
        .p4d_val = PV_CALLEE_SAVE(xen_p4d_val),
        .make_p4d = PV_CALLEE_SAVE(xen_make_p4d),
 #endif
-#endif /* CONFIG_X86_64 */
 
        .activate_mm = xen_activate_mm,
        .dup_mmap = xen_dup_mmap,
index 0acba2c..be4151f 100644 (file)
@@ -379,12 +379,8 @@ static void __init xen_rebuild_p2m_list(unsigned long *p2m)
 
                if (type == P2M_TYPE_PFN || i < chunk) {
                        /* Use initial p2m page contents. */
-#ifdef CONFIG_X86_64
                        mfns = alloc_p2m_page();
                        copy_page(mfns, xen_p2m_addr + pfn);
-#else
-                       mfns = xen_p2m_addr + pfn;
-#endif
                        ptep = populate_extra_pte((unsigned long)(p2m + pfn));
                        set_pte(ptep,
                                pfn_pte(PFN_DOWN(__pa(mfns)), PAGE_KERNEL));
@@ -467,7 +463,7 @@ EXPORT_SYMBOL_GPL(get_phys_to_machine);
  * Allocate new pmd(s). It is checked whether the old pmd is still in place.
  * If not, nothing is changed. This is okay as the only reason for allocating
  * a new pmd is to replace p2m_missing_pte or p2m_identity_pte by a individual
- * pmd. In case of PAE/x86-32 there are multiple pmds to allocate!
+ * pmd.
  */
 static pte_t *alloc_p2m_pmd(unsigned long addr, pte_t *pte_pg)
 {
index 3566e37..7eab14d 100644 (file)
@@ -32,7 +32,6 @@
 #include <xen/features.h>
 #include <xen/hvc-console.h>
 #include "xen-ops.h"
-#include "vdso.h"
 #include "mmu.h"
 
 #define GB(x) ((uint64_t)(x) * 1024 * 1024 * 1024)
@@ -545,13 +544,10 @@ static unsigned long __init xen_get_pages_limit(void)
 {
        unsigned long limit;
 
-#ifdef CONFIG_X86_32
-       limit = GB(64) / PAGE_SIZE;
-#else
        limit = MAXMEM / PAGE_SIZE;
        if (!xen_initial_domain() && xen_512gb_limit)
                limit = GB(512) / PAGE_SIZE;
-#endif
+
        return limit;
 }
 
@@ -722,17 +718,8 @@ static void __init xen_reserve_xen_mfnlist(void)
        if (!xen_is_e820_reserved(start, size))
                return;
 
-#ifdef CONFIG_X86_32
-       /*
-        * Relocating the p2m on 32 bit system to an arbitrary virtual address
-        * is not supported, so just give up.
-        */
-       xen_raw_console_write("Xen hypervisor allocated p2m list conflicts with E820 map\n");
-       BUG();
-#else
        xen_relocate_p2m();
        memblock_free(start, size);
-#endif
 }
 
 /**
@@ -921,20 +908,6 @@ char * __init xen_memory_setup(void)
        return "Xen";
 }
 
-/*
- * Set the bit indicating "nosegneg" library variants should be used.
- * We only need to bother in pure 32-bit mode; compat 32-bit processes
- * can have un-truncated segments, so wrapping around is allowed.
- */
-static void __init fiddle_vdso(void)
-{
-#ifdef CONFIG_X86_32
-       u32 *mask = vdso_image_32.data +
-               vdso_image_32.sym_VDSO32_NOTE_MASK;
-       *mask |= 1 << VDSO_NOTE_NONEGSEG_BIT;
-#endif
-}
-
 static int register_callback(unsigned type, const void *func)
 {
        struct callback_register callback = {
@@ -951,11 +924,7 @@ void xen_enable_sysenter(void)
        int ret;
        unsigned sysenter_feature;
 
-#ifdef CONFIG_X86_32
-       sysenter_feature = X86_FEATURE_SEP;
-#else
        sysenter_feature = X86_FEATURE_SYSENTER32;
-#endif
 
        if (!boot_cpu_has(sysenter_feature))
                return;
@@ -967,7 +936,6 @@ void xen_enable_sysenter(void)
 
 void xen_enable_syscall(void)
 {
-#ifdef CONFIG_X86_64
        int ret;
 
        ret = register_callback(CALLBACKTYPE_syscall, xen_syscall_target);
@@ -983,7 +951,6 @@ void xen_enable_syscall(void)
                if (ret != 0)
                        setup_clear_cpu_cap(X86_FEATURE_SYSCALL32);
        }
-#endif /* CONFIG_X86_64 */
 }
 
 static void __init xen_pvmmu_arch_setup(void)
@@ -1024,7 +991,6 @@ void __init xen_arch_setup(void)
        disable_cpuidle();
        disable_cpufreq();
        WARN_ON(xen_set_default_idle());
-       fiddle_vdso();
 #ifdef CONFIG_NUMA
        numa_off = 1;
 #endif
index 47c8f4b..c2ac319 100644 (file)
@@ -211,15 +211,6 @@ static void __init xen_pv_smp_prepare_boot_cpu(void)
                 * sure the old memory can be recycled. */
                make_lowmem_page_readwrite(xen_initial_gdt);
 
-#ifdef CONFIG_X86_32
-       /*
-        * Xen starts us with XEN_FLAT_RING1_DS, but linux code
-        * expects __USER_DS
-        */
-       loadsegment(ds, __USER_DS);
-       loadsegment(es, __USER_DS);
-#endif
-
        xen_filter_cpu_maps();
        xen_setup_vcpu_info_placement();
 
@@ -300,10 +291,6 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 
        gdt = get_cpu_gdt_rw(cpu);
 
-#ifdef CONFIG_X86_32
-       ctxt->user_regs.fs = __KERNEL_PERCPU;
-       ctxt->user_regs.gs = __KERNEL_STACK_CANARY;
-#endif
        memset(&ctxt->fpu_ctxt, 0, sizeof(ctxt->fpu_ctxt));
 
        /*
@@ -341,12 +328,7 @@ cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
        ctxt->kernel_ss = __KERNEL_DS;
        ctxt->kernel_sp = task_top_of_stack(idle);
 
-#ifdef CONFIG_X86_32
-       ctxt->event_callback_cs     = __KERNEL_CS;
-       ctxt->failsafe_callback_cs  = __KERNEL_CS;
-#else
        ctxt->gs_base_kernel = per_cpu_offset(cpu);
-#endif
        ctxt->event_callback_eip    =
                (unsigned long)xen_asm_exc_xen_hypervisor_callback;
        ctxt->failsafe_callback_eip =
diff --git a/arch/x86/xen/vdso.h b/arch/x86/xen/vdso.h
deleted file mode 100644 (file)
index 873c54c..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-/* Bit used for the pseudo-hwcap for non-negative segments.  We use
-   bit 1 to avoid bugs in some versions of glibc when bit 0 is
-   used; the choice is otherwise arbitrary. */
-#define VDSO_NOTE_NONEGSEG_BIT 1
index 508fe20..1cb0e84 100644 (file)
@@ -6,12 +6,18 @@
  * operations here; the indirect forms are better handled in C.
  */
 
+#include <asm/errno.h>
 #include <asm/asm-offsets.h>
 #include <asm/percpu.h>
 #include <asm/processor-flags.h>
-#include <asm/frame.h>
+#include <asm/segment.h>
+#include <asm/thread_info.h>
 #include <asm/asm.h>
+#include <asm/frame.h>
 
+#include <xen/interface/xen.h>
+
+#include <linux/init.h>
 #include <linux/linkage.h>
 
 /*
@@ -76,11 +82,7 @@ SYM_FUNC_END(xen_save_fl_direct)
  */
 SYM_FUNC_START(xen_restore_fl_direct)
        FRAME_BEGIN
-#ifdef CONFIG_X86_64
        testw $X86_EFLAGS_IF, %di
-#else
-       testb $X86_EFLAGS_IF>>8, %ah
-#endif
        setz PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
        /*
         * Preempt here doesn't matter because that will deal with any
@@ -104,15 +106,6 @@ SYM_FUNC_END(xen_restore_fl_direct)
  */
 SYM_FUNC_START(check_events)
        FRAME_BEGIN
-#ifdef CONFIG_X86_32
-       push %eax
-       push %ecx
-       push %edx
-       call xen_force_evtchn_callback
-       pop %edx
-       pop %ecx
-       pop %eax
-#else
        push %rax
        push %rcx
        push %rdx
@@ -132,7 +125,6 @@ SYM_FUNC_START(check_events)
        pop %rdx
        pop %rcx
        pop %rax
-#endif
        FRAME_END
        ret
 SYM_FUNC_END(check_events)
@@ -151,3 +143,175 @@ SYM_FUNC_START(xen_read_cr2_direct)
        FRAME_END
        ret
 SYM_FUNC_END(xen_read_cr2_direct);
+
+.macro xen_pv_trap name
+SYM_CODE_START(xen_\name)
+       pop %rcx
+       pop %r11
+       jmp  \name
+SYM_CODE_END(xen_\name)
+_ASM_NOKPROBE(xen_\name)
+.endm
+
+xen_pv_trap asm_exc_divide_error
+xen_pv_trap asm_xenpv_exc_debug
+xen_pv_trap asm_exc_int3
+xen_pv_trap asm_xenpv_exc_nmi
+xen_pv_trap asm_exc_overflow
+xen_pv_trap asm_exc_bounds
+xen_pv_trap asm_exc_invalid_op
+xen_pv_trap asm_exc_device_not_available
+xen_pv_trap asm_exc_double_fault
+xen_pv_trap asm_exc_coproc_segment_overrun
+xen_pv_trap asm_exc_invalid_tss
+xen_pv_trap asm_exc_segment_not_present
+xen_pv_trap asm_exc_stack_segment
+xen_pv_trap asm_exc_general_protection
+xen_pv_trap asm_exc_page_fault
+xen_pv_trap asm_exc_spurious_interrupt_bug
+xen_pv_trap asm_exc_coprocessor_error
+xen_pv_trap asm_exc_alignment_check
+#ifdef CONFIG_X86_MCE
+xen_pv_trap asm_exc_machine_check
+#endif /* CONFIG_X86_MCE */
+xen_pv_trap asm_exc_simd_coprocessor_error
+#ifdef CONFIG_IA32_EMULATION
+xen_pv_trap entry_INT80_compat
+#endif
+xen_pv_trap asm_exc_xen_hypervisor_callback
+
+       __INIT
+SYM_CODE_START(xen_early_idt_handler_array)
+       i = 0
+       .rept NUM_EXCEPTION_VECTORS
+       pop %rcx
+       pop %r11
+       jmp early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE
+       i = i + 1
+       .fill xen_early_idt_handler_array + i*XEN_EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
+       .endr
+SYM_CODE_END(xen_early_idt_handler_array)
+       __FINIT
+
+hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32
+/*
+ * Xen64 iret frame:
+ *
+ *     ss
+ *     rsp
+ *     rflags
+ *     cs
+ *     rip             <-- standard iret frame
+ *
+ *     flags
+ *
+ *     rcx             }
+ *     r11             }<-- pushed by hypercall page
+ * rsp->rax            }
+ */
+SYM_CODE_START(xen_iret)
+       pushq $0
+       jmp hypercall_iret
+SYM_CODE_END(xen_iret)
+
+SYM_CODE_START(xen_sysret64)
+       /*
+        * We're already on the usermode stack at this point, but
+        * still with the kernel gs, so we can easily switch back.
+        *
+        * tss.sp2 is scratch space.
+        */
+       movq %rsp, PER_CPU_VAR(cpu_tss_rw + TSS_sp2)
+       movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+
+       pushq $__USER_DS
+       pushq PER_CPU_VAR(cpu_tss_rw + TSS_sp2)
+       pushq %r11
+       pushq $__USER_CS
+       pushq %rcx
+
+       pushq $VGCF_in_syscall
+       jmp hypercall_iret
+SYM_CODE_END(xen_sysret64)
+
+/*
+ * Xen handles syscall callbacks much like ordinary exceptions, which
+ * means we have:
+ * - kernel gs
+ * - kernel rsp
+ * - an iret-like stack frame on the stack (including rcx and r11):
+ *     ss
+ *     rsp
+ *     rflags
+ *     cs
+ *     rip
+ *     r11
+ * rsp->rcx
+ */
+
+/* Normal 64-bit system call target */
+SYM_FUNC_START(xen_syscall_target)
+       popq %rcx
+       popq %r11
+
+       /*
+        * Neither Xen nor the kernel really knows what the old SS and
+        * CS were.  The kernel expects __USER_DS and __USER_CS, so
+        * report those values even though Xen will guess its own values.
+        */
+       movq $__USER_DS, 4*8(%rsp)
+       movq $__USER_CS, 1*8(%rsp)
+
+       jmp entry_SYSCALL_64_after_hwframe
+SYM_FUNC_END(xen_syscall_target)
+
+#ifdef CONFIG_IA32_EMULATION
+
+/* 32-bit compat syscall target */
+SYM_FUNC_START(xen_syscall32_target)
+       popq %rcx
+       popq %r11
+
+       /*
+        * Neither Xen nor the kernel really knows what the old SS and
+        * CS were.  The kernel expects __USER32_DS and __USER32_CS, so
+        * report those values even though Xen will guess its own values.
+        */
+       movq $__USER32_DS, 4*8(%rsp)
+       movq $__USER32_CS, 1*8(%rsp)
+
+       jmp entry_SYSCALL_compat_after_hwframe
+SYM_FUNC_END(xen_syscall32_target)
+
+/* 32-bit compat sysenter target */
+SYM_FUNC_START(xen_sysenter_target)
+       /*
+        * NB: Xen is polite and clears TF from EFLAGS for us.  This means
+        * that we don't need to guard against single step exceptions here.
+        */
+       popq %rcx
+       popq %r11
+
+       /*
+        * Neither Xen nor the kernel really knows what the old SS and
+        * CS were.  The kernel expects __USER32_DS and __USER32_CS, so
+        * report those values even though Xen will guess its own values.
+        */
+       movq $__USER32_DS, 4*8(%rsp)
+       movq $__USER32_CS, 1*8(%rsp)
+
+       jmp entry_SYSENTER_compat_after_hwframe
+SYM_FUNC_END(xen_sysenter_target)
+
+#else /* !CONFIG_IA32_EMULATION */
+
+SYM_FUNC_START_ALIAS(xen_syscall32_target)
+SYM_FUNC_START(xen_sysenter_target)
+       lea 16(%rsp), %rsp      /* strip %rcx, %r11 */
+       mov $-ENOSYS, %rax
+       pushq $0
+       jmp hypercall_iret
+SYM_FUNC_END(xen_sysenter_target)
+SYM_FUNC_END_ALIAS(xen_syscall32_target)
+
+#endif /* CONFIG_IA32_EMULATION */
diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S
deleted file mode 100644 (file)
index 4757cec..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Asm versions of Xen pv-ops, suitable for direct use.
- *
- * We only bother with direct forms (ie, vcpu in pda) of the
- * operations here; the indirect forms are better handled in C.
- */
-
-#include <asm/thread_info.h>
-#include <asm/processor-flags.h>
-#include <asm/segment.h>
-#include <asm/asm.h>
-
-#include <xen/interface/xen.h>
-
-#include <linux/linkage.h>
-
-/* Pseudo-flag used for virtual NMI, which we don't implement yet */
-#define XEN_EFLAGS_NMI  0x80000000
-
-/*
- * This is run where a normal iret would be run, with the same stack setup:
- *     8: eflags
- *     4: cs
- *     esp-> 0: eip
- *
- * This attempts to make sure that any pending events are dealt with
- * on return to usermode, but there is a small window in which an
- * event can happen just before entering usermode.  If the nested
- * interrupt ends up setting one of the TIF_WORK_MASK pending work
- * flags, they will not be tested again before returning to
- * usermode. This means that a process can end up with pending work,
- * which will be unprocessed until the process enters and leaves the
- * kernel again, which could be an unbounded amount of time.  This
- * means that a pending signal or reschedule event could be
- * indefinitely delayed.
- *
- * The fix is to notice a nested interrupt in the critical window, and
- * if one occurs, then fold the nested interrupt into the current
- * interrupt stack frame, and re-process it iteratively rather than
- * recursively.  This means that it will exit via the normal path, and
- * all pending work will be dealt with appropriately.
- *
- * Because the nested interrupt handler needs to deal with the current
- * stack state in whatever form its in, we keep things simple by only
- * using a single register which is pushed/popped on the stack.
- */
-
-.macro POP_FS
-1:
-       popw %fs
-.pushsection .fixup, "ax"
-2:     movw $0, (%esp)
-       jmp 1b
-.popsection
-       _ASM_EXTABLE(1b,2b)
-.endm
-
-SYM_CODE_START(xen_iret)
-       /* test eflags for special cases */
-       testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp)
-       jnz hyper_iret
-
-       push %eax
-       ESP_OFFSET=4    # bytes pushed onto stack
-
-       /* Store vcpu_info pointer for easy access */
-#ifdef CONFIG_SMP
-       pushw %fs
-       movl $(__KERNEL_PERCPU), %eax
-       movl %eax, %fs
-       movl %fs:xen_vcpu, %eax
-       POP_FS
-#else
-       movl %ss:xen_vcpu, %eax
-#endif
-
-       /* check IF state we're restoring */
-       testb $X86_EFLAGS_IF>>8, 8+1+ESP_OFFSET(%esp)
-
-       /*
-        * Maybe enable events.  Once this happens we could get a
-        * recursive event, so the critical region starts immediately
-        * afterwards.  However, if that happens we don't end up
-        * resuming the code, so we don't have to be worried about
-        * being preempted to another CPU.
-        */
-       setz %ss:XEN_vcpu_info_mask(%eax)
-xen_iret_start_crit:
-
-       /* check for unmasked and pending */
-       cmpw $0x0001, %ss:XEN_vcpu_info_pending(%eax)
-
-       /*
-        * If there's something pending, mask events again so we can
-        * jump back into exc_xen_hypervisor_callback. Otherwise do not
-        * touch XEN_vcpu_info_mask.
-        */
-       jne 1f
-       movb $1, %ss:XEN_vcpu_info_mask(%eax)
-
-1:     popl %eax
-
-       /*
-        * From this point on the registers are restored and the stack
-        * updated, so we don't need to worry about it if we're
-        * preempted
-        */
-iret_restore_end:
-
-       /*
-        * Jump to hypervisor_callback after fixing up the stack.
-        * Events are masked, so jumping out of the critical region is
-        * OK.
-        */
-       je xen_asm_exc_xen_hypervisor_callback
-
-1:     iret
-xen_iret_end_crit:
-       _ASM_EXTABLE(1b, asm_iret_error)
-
-hyper_iret:
-       /* put this out of line since its very rarely used */
-       jmp hypercall_page + __HYPERVISOR_iret * 32
-SYM_CODE_END(xen_iret)
-
-       .globl xen_iret_start_crit, xen_iret_end_crit
-
-/*
- * This is called by xen_asm_exc_xen_hypervisor_callback in entry_32.S when it sees
- * that the EIP at the time of interrupt was between
- * xen_iret_start_crit and xen_iret_end_crit.
- *
- * The stack format at this point is:
- *     ----------------
- *      ss             : (ss/esp may be present if we came from usermode)
- *      esp            :
- *      eflags         }  outer exception info
- *      cs             }
- *      eip            }
- *     ----------------
- *      eax            :  outer eax if it hasn't been restored
- *     ----------------
- *      eflags         }
- *      cs             }  nested exception info
- *      eip            }
- *      return address : (into xen_asm_exc_xen_hypervisor_callback)
- *
- * In order to deliver the nested exception properly, we need to discard the
- * nested exception frame such that when we handle the exception, we do it
- * in the context of the outer exception rather than starting a new one.
- *
- * The only caveat is that if the outer eax hasn't been restored yet (i.e.
- * it's still on stack), we need to restore its value here.
-*/
-.pushsection .noinstr.text, "ax"
-SYM_CODE_START(xen_iret_crit_fixup)
-       /*
-        * Paranoia: Make sure we're really coming from kernel space.
-        * One could imagine a case where userspace jumps into the
-        * critical range address, but just before the CPU delivers a
-        * PF, it decides to deliver an interrupt instead.  Unlikely?
-        * Definitely.  Easy to avoid?  Yes.
-        */
-       testb $2, 2*4(%esp)             /* nested CS */
-       jnz 2f
-
-       /*
-        * If eip is before iret_restore_end then stack
-        * hasn't been restored yet.
-        */
-       cmpl $iret_restore_end, 1*4(%esp)
-       jae 1f
-
-       movl 4*4(%esp), %eax            /* load outer EAX */
-       ret $4*4                        /* discard nested EIP, CS, and EFLAGS as
-                                        * well as the just restored EAX */
-
-1:
-       ret $3*4                        /* discard nested EIP, CS, and EFLAGS */
-
-2:
-       ret
-SYM_CODE_END(xen_iret_crit_fixup)
-.popsection
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
deleted file mode 100644 (file)
index aab1d99..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Asm versions of Xen pv-ops, suitable for direct use.
- *
- * We only bother with direct forms (ie, vcpu in pda) of the
- * operations here; the indirect forms are better handled in C.
- */
-
-#include <asm/errno.h>
-#include <asm/percpu.h>
-#include <asm/processor-flags.h>
-#include <asm/segment.h>
-#include <asm/asm-offsets.h>
-#include <asm/thread_info.h>
-#include <asm/asm.h>
-
-#include <xen/interface/xen.h>
-
-#include <linux/init.h>
-#include <linux/linkage.h>
-
-.macro xen_pv_trap name
-SYM_CODE_START(xen_\name)
-       pop %rcx
-       pop %r11
-       jmp  \name
-SYM_CODE_END(xen_\name)
-_ASM_NOKPROBE(xen_\name)
-.endm
-
-xen_pv_trap asm_exc_divide_error
-xen_pv_trap asm_xenpv_exc_debug
-xen_pv_trap asm_exc_int3
-xen_pv_trap asm_xenpv_exc_nmi
-xen_pv_trap asm_exc_overflow
-xen_pv_trap asm_exc_bounds
-xen_pv_trap asm_exc_invalid_op
-xen_pv_trap asm_exc_device_not_available
-xen_pv_trap asm_exc_double_fault
-xen_pv_trap asm_exc_coproc_segment_overrun
-xen_pv_trap asm_exc_invalid_tss
-xen_pv_trap asm_exc_segment_not_present
-xen_pv_trap asm_exc_stack_segment
-xen_pv_trap asm_exc_general_protection
-xen_pv_trap asm_exc_page_fault
-xen_pv_trap asm_exc_spurious_interrupt_bug
-xen_pv_trap asm_exc_coprocessor_error
-xen_pv_trap asm_exc_alignment_check
-#ifdef CONFIG_X86_MCE
-xen_pv_trap asm_exc_machine_check
-#endif /* CONFIG_X86_MCE */
-xen_pv_trap asm_exc_simd_coprocessor_error
-#ifdef CONFIG_IA32_EMULATION
-xen_pv_trap entry_INT80_compat
-#endif
-xen_pv_trap asm_exc_xen_hypervisor_callback
-
-       __INIT
-SYM_CODE_START(xen_early_idt_handler_array)
-       i = 0
-       .rept NUM_EXCEPTION_VECTORS
-       pop %rcx
-       pop %r11
-       jmp early_idt_handler_array + i*EARLY_IDT_HANDLER_SIZE
-       i = i + 1
-       .fill xen_early_idt_handler_array + i*XEN_EARLY_IDT_HANDLER_SIZE - ., 1, 0xcc
-       .endr
-SYM_CODE_END(xen_early_idt_handler_array)
-       __FINIT
-
-hypercall_iret = hypercall_page + __HYPERVISOR_iret * 32
-/*
- * Xen64 iret frame:
- *
- *     ss
- *     rsp
- *     rflags
- *     cs
- *     rip             <-- standard iret frame
- *
- *     flags
- *
- *     rcx             }
- *     r11             }<-- pushed by hypercall page
- * rsp->rax            }
- */
-SYM_CODE_START(xen_iret)
-       pushq $0
-       jmp hypercall_iret
-SYM_CODE_END(xen_iret)
-
-SYM_CODE_START(xen_sysret64)
-       /*
-        * We're already on the usermode stack at this point, but
-        * still with the kernel gs, so we can easily switch back.
-        *
-        * tss.sp2 is scratch space.
-        */
-       movq %rsp, PER_CPU_VAR(cpu_tss_rw + TSS_sp2)
-       movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
-
-       pushq $__USER_DS
-       pushq PER_CPU_VAR(cpu_tss_rw + TSS_sp2)
-       pushq %r11
-       pushq $__USER_CS
-       pushq %rcx
-
-       pushq $VGCF_in_syscall
-       jmp hypercall_iret
-SYM_CODE_END(xen_sysret64)
-
-/*
- * Xen handles syscall callbacks much like ordinary exceptions, which
- * means we have:
- * - kernel gs
- * - kernel rsp
- * - an iret-like stack frame on the stack (including rcx and r11):
- *     ss
- *     rsp
- *     rflags
- *     cs
- *     rip
- *     r11
- * rsp->rcx
- */
-
-/* Normal 64-bit system call target */
-SYM_FUNC_START(xen_syscall_target)
-       popq %rcx
-       popq %r11
-
-       /*
-        * Neither Xen nor the kernel really knows what the old SS and
-        * CS were.  The kernel expects __USER_DS and __USER_CS, so
-        * report those values even though Xen will guess its own values.
-        */
-       movq $__USER_DS, 4*8(%rsp)
-       movq $__USER_CS, 1*8(%rsp)
-
-       jmp entry_SYSCALL_64_after_hwframe
-SYM_FUNC_END(xen_syscall_target)
-
-#ifdef CONFIG_IA32_EMULATION
-
-/* 32-bit compat syscall target */
-SYM_FUNC_START(xen_syscall32_target)
-       popq %rcx
-       popq %r11
-
-       /*
-        * Neither Xen nor the kernel really knows what the old SS and
-        * CS were.  The kernel expects __USER32_DS and __USER32_CS, so
-        * report those values even though Xen will guess its own values.
-        */
-       movq $__USER32_DS, 4*8(%rsp)
-       movq $__USER32_CS, 1*8(%rsp)
-
-       jmp entry_SYSCALL_compat_after_hwframe
-SYM_FUNC_END(xen_syscall32_target)
-
-/* 32-bit compat sysenter target */
-SYM_FUNC_START(xen_sysenter_target)
-       /*
-        * NB: Xen is polite and clears TF from EFLAGS for us.  This means
-        * that we don't need to guard against single step exceptions here.
-        */
-       popq %rcx
-       popq %r11
-
-       /*
-        * Neither Xen nor the kernel really knows what the old SS and
-        * CS were.  The kernel expects __USER32_DS and __USER32_CS, so
-        * report those values even though Xen will guess its own values.
-        */
-       movq $__USER32_DS, 4*8(%rsp)
-       movq $__USER32_CS, 1*8(%rsp)
-
-       jmp entry_SYSENTER_compat_after_hwframe
-SYM_FUNC_END(xen_sysenter_target)
-
-#else /* !CONFIG_IA32_EMULATION */
-
-SYM_FUNC_START_ALIAS(xen_syscall32_target)
-SYM_FUNC_START(xen_sysenter_target)
-       lea 16(%rsp), %rsp      /* strip %rcx, %r11 */
-       mov $-ENOSYS, %rax
-       pushq $0
-       jmp hypercall_iret
-SYM_FUNC_END(xen_sysenter_target)
-SYM_FUNC_END_ALIAS(xen_syscall32_target)
-
-#endif /* CONFIG_IA32_EMULATION */
index 1ba601d..2d7c8f3 100644 (file)
@@ -35,13 +35,8 @@ SYM_CODE_START(startup_xen)
        rep __ASM_SIZE(stos)
 
        mov %_ASM_SI, xen_start_info
-#ifdef CONFIG_X86_64
        mov initial_stack(%rip), %rsp
-#else
-       mov initial_stack, %esp
-#endif
 
-#ifdef CONFIG_X86_64
        /* Set up %gs.
         *
         * The base of %gs always points to fixed_percpu_data.  If the
@@ -53,7 +48,6 @@ SYM_CODE_START(startup_xen)
        movq    $INIT_PER_CPU_VAR(fixed_percpu_data),%rax
        cdq
        wrmsr
-#endif
 
        call xen_start_kernel
 SYM_CODE_END(startup_xen)
index 53b224f..45d556f 100644 (file)
@@ -33,7 +33,6 @@ void xen_setup_mfn_list_list(void);
 void xen_build_mfn_list_list(void);
 void xen_setup_machphys_mapping(void);
 void xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
-void xen_reserve_top(void);
 void __init xen_reserve_special_pages(void);
 void __init xen_pt_check_e820(void);
 
index d216ccb..6276e3c 100644 (file)
 204    common  quotactl                        sys_quotactl
 # 205 was old nfsservctl
 205    common  nfsservctl                      sys_ni_syscall
-206    common  _sysctl                         sys_sysctl
+206    common  _sysctl                         sys_ni_syscall
 207    common  bdflush                         sys_bdflush
 208    common  uname                           sys_newuname
 209    common  sysinfo                         sys_sysinfo
index 6e1543c..53abb5c 100644 (file)
@@ -308,9 +308,16 @@ static void blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq,
        flush_rq->mq_ctx = first_rq->mq_ctx;
        flush_rq->mq_hctx = first_rq->mq_hctx;
 
-       if (!q->elevator)
+       if (!q->elevator) {
                flush_rq->tag = first_rq->tag;
-       else
+
+               /*
+                * We borrow data request's driver tag, so have to mark
+                * this flush request as INFLIGHT for avoiding double
+                * account of this driver tag
+                */
+               flush_rq->rq_flags |= RQF_MQ_INFLIGHT;
+       } else
                flush_rq->internal_tag = first_rq->internal_tag;
 
        flush_rq->cmd_flags = REQ_OP_FLUSH | REQ_PREFLUSH;
index 019e09b..0d1811e 100644 (file)
@@ -47,6 +47,15 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
                op = REQ_OP_DISCARD;
        }
 
+       /* In case the discard granularity isn't set by buggy device driver */
+       if (WARN_ON_ONCE(!q->limits.discard_granularity)) {
+               char dev_name[BDEVNAME_SIZE];
+
+               bdevname(bdev, dev_name);
+               pr_err_ratelimited("%s: Error: discard_granularity is 0.\n", dev_name);
+               return -EOPNOTSUPP;
+       }
+
        bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
        if ((sector | nr_sects) & bs_mask)
                return -EINVAL;
index c176784..21efa78 100644 (file)
@@ -554,12 +554,6 @@ static int aead_accept_parent_nokey(void *private, struct sock *sk)
 
        INIT_LIST_HEAD(&ctx->tsgl_list);
        ctx->len = len;
-       ctx->used = 0;
-       atomic_set(&ctx->rcvused, 0);
-       ctx->more = 0;
-       ctx->merge = 0;
-       ctx->enc = 0;
-       ctx->aead_assoclen = 0;
        crypto_init_wait(&ctx->wait);
 
        ask->private = ctx;
index 5c112b2..478f3b8 100644 (file)
@@ -329,6 +329,7 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
        ctx = sock_kmalloc(sk, len, GFP_KERNEL);
        if (!ctx)
                return -ENOMEM;
+       memset(ctx, 0, len);
 
        ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(tfm),
                               GFP_KERNEL);
@@ -336,16 +337,10 @@ static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
                sock_kfree_s(sk, ctx, len);
                return -ENOMEM;
        }
-
        memset(ctx->iv, 0, crypto_skcipher_ivsize(tfm));
 
        INIT_LIST_HEAD(&ctx->tsgl_list);
        ctx->len = len;
-       ctx->used = 0;
-       atomic_set(&ctx->rcvused, 0);
-       ctx->more = 0;
-       ctx->merge = 0;
-       ctx->enc = 0;
        crypto_init_wait(&ctx->wait);
 
        ask->private = ctx;
index ba2612e..4c34837 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include <linux/clk-provider.h>
-#include <linux/platform_data/clk-st.h>
+#include <linux/platform_data/clk-fch.h>
 #include <linux/platform_device.h>
 #include <linux/pm_domain.h>
 #include <linux/clkdev.h>
@@ -79,11 +79,12 @@ static int misc_check_res(struct acpi_resource *ares, void *data)
        return !acpi_dev_resource_memory(ares, &res);
 }
 
-static int st_misc_setup(struct apd_private_data *pdata)
+static int fch_misc_setup(struct apd_private_data *pdata)
 {
        struct acpi_device *adev = pdata->adev;
+       const union acpi_object *obj;
        struct platform_device *clkdev;
-       struct st_clk_data *clk_data;
+       struct fch_clk_data *clk_data;
        struct resource_entry *rentry;
        struct list_head resource_list;
        int ret;
@@ -98,6 +99,9 @@ static int st_misc_setup(struct apd_private_data *pdata)
        if (ret < 0)
                return -ENOENT;
 
+       acpi_dev_get_property(adev, "is-rv", ACPI_TYPE_INTEGER, &obj);
+       clk_data->is_rv = obj->integer.value;
+
        list_for_each_entry(rentry, &resource_list, node) {
                clk_data->base = devm_ioremap(&adev->dev, rentry->res->start,
                                              resource_size(rentry->res));
@@ -106,7 +110,7 @@ static int st_misc_setup(struct apd_private_data *pdata)
 
        acpi_dev_free_resource_list(&resource_list);
 
-       clkdev = platform_device_register_data(&adev->dev, "clk-st",
+       clkdev = platform_device_register_data(&adev->dev, "clk-fch",
                                               PLATFORM_DEVID_NONE, clk_data,
                                               sizeof(*clk_data));
        return PTR_ERR_OR_ZERO(clkdev);
@@ -135,8 +139,8 @@ static const struct apd_device_desc cz_uart_desc = {
        .properties = uart_properties,
 };
 
-static const struct apd_device_desc st_misc_desc = {
-       .setup = st_misc_setup,
+static const struct apd_device_desc fch_misc_desc = {
+       .setup = fch_misc_setup,
 };
 #endif
 
@@ -239,7 +243,8 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
        { "AMD0020", APD_ADDR(cz_uart_desc) },
        { "AMDI0020", APD_ADDR(cz_uart_desc) },
        { "AMD0030", },
-       { "AMD0040", APD_ADDR(st_misc_desc)},
+       { "AMD0040", APD_ADDR(fch_misc_desc)},
+       { "HYGO0010", APD_ADDR(wt_i2c_desc) },
 #endif
 #ifdef CONFIG_ARM64
        { "APMC0D0F", APD_ADDR(xgene_i2c_desc) },
index d181601..2f137d6 100644 (file)
@@ -1171,6 +1171,8 @@ static int loop_configure(struct loop_device *lo, fmode_t mode,
        if (part_shift)
                lo->lo_flags |= LO_FLAGS_PARTSCAN;
        partscan = lo->lo_flags & LO_FLAGS_PARTSCAN;
+       if (partscan)
+               lo->lo_disk->flags &= ~GENHD_FL_NO_PART_SCAN;
 
        /* Grab the block_device to prevent its destruction after we
         * put /dev/loopXX inode. Later in __loop_clr_fd() we bdput(bdev).
index 5eddfd2..b241a09 100644 (file)
@@ -45,7 +45,7 @@ void rnbd_dev_close(struct rnbd_dev *dev)
        kfree(dev);
 }
 
-static void rnbd_dev_bi_end_io(struct bio *bio)
+void rnbd_dev_bi_end_io(struct bio *bio)
 {
        struct rnbd_dev_blk_io *io = bio->bi_private;
 
@@ -63,8 +63,8 @@ static void rnbd_dev_bi_end_io(struct bio *bio)
  *     Map the kernel address into a bio suitable for io to a block
  *     device. Returns an error pointer in case of error.
  */
-static struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
-                                    unsigned int len, gfp_t gfp_mask)
+struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
+                             unsigned int len, gfp_t gfp_mask)
 {
        unsigned long kaddr = (unsigned long)data;
        unsigned long end = (kaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT;
@@ -99,36 +99,5 @@ static struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
                offset = 0;
        }
 
-       bio->bi_end_io = bio_put;
        return bio;
 }
-
-int rnbd_dev_submit_io(struct rnbd_dev *dev, sector_t sector, void *data,
-                      size_t len, u32 bi_size, enum rnbd_io_flags flags,
-                      short prio, void *priv)
-{
-       struct rnbd_dev_blk_io *io;
-       struct bio *bio;
-
-       /* Generate bio with pages pointing to the rdma buffer */
-       bio = rnbd_bio_map_kern(data, dev->ibd_bio_set, len, GFP_KERNEL);
-       if (IS_ERR(bio))
-               return PTR_ERR(bio);
-
-       io = container_of(bio, struct rnbd_dev_blk_io, bio);
-
-       io->dev = dev;
-       io->priv = priv;
-
-       bio->bi_end_io = rnbd_dev_bi_end_io;
-       bio->bi_private = io;
-       bio->bi_opf = rnbd_to_bio_flags(flags);
-       bio->bi_iter.bi_sector = sector;
-       bio->bi_iter.bi_size = bi_size;
-       bio_set_prio(bio, prio);
-       bio_set_dev(bio, dev->bdev);
-
-       submit_bio(bio);
-
-       return 0;
-}
index 0f65b09..0eb2385 100644 (file)
@@ -41,6 +41,11 @@ void rnbd_dev_close(struct rnbd_dev *dev);
 
 void rnbd_endio(void *priv, int error);
 
+void rnbd_dev_bi_end_io(struct bio *bio);
+
+struct bio *rnbd_bio_map_kern(void *data, struct bio_set *bs,
+                             unsigned int len, gfp_t gfp_mask);
+
 static inline int rnbd_dev_get_max_segs(const struct rnbd_dev *dev)
 {
        return queue_max_segments(bdev_get_queue(dev->bdev));
@@ -75,18 +80,4 @@ static inline int rnbd_dev_get_discard_alignment(const struct rnbd_dev *dev)
        return bdev_get_queue(dev->bdev)->limits.discard_alignment;
 }
 
-/**
- * rnbd_dev_submit_io() - Submit an I/O to the disk
- * @dev:       device to that the I/O is submitted
- * @sector:    address to read/write data to
- * @data:      I/O data to write or buffer to read I/O date into
- * @len:       length of @data
- * @bi_size:   Amount of data that will be read/written
- * @prio:       IO priority
- * @priv:      private data passed to @io_fn
- */
-int rnbd_dev_submit_io(struct rnbd_dev *dev, sector_t sector, void *data,
-                       size_t len, u32 bi_size, enum rnbd_io_flags flags,
-                       short prio, void *priv);
-
 #endif /* RNBD_SRV_DEV_H */
index 86e6152..0fb9484 100644 (file)
@@ -124,6 +124,9 @@ static int process_rdma(struct rtrs_srv *sess,
        struct rnbd_srv_sess_dev *sess_dev;
        u32 dev_id;
        int err;
+       struct rnbd_dev_blk_io *io;
+       struct bio *bio;
+       short prio;
 
        priv = kmalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
@@ -142,18 +145,29 @@ static int process_rdma(struct rtrs_srv *sess,
        priv->sess_dev = sess_dev;
        priv->id = id;
 
-       err = rnbd_dev_submit_io(sess_dev->rnbd_dev, le64_to_cpu(msg->sector),
-                                 data, datalen, le32_to_cpu(msg->bi_size),
-                                 le32_to_cpu(msg->rw),
-                                 srv_sess->ver < RNBD_PROTO_VER_MAJOR ||
-                                 usrlen < sizeof(*msg) ?
-                                 0 : le16_to_cpu(msg->prio), priv);
-       if (unlikely(err)) {
-               rnbd_srv_err(sess_dev, "Submitting I/O to device failed, err: %d\n",
-                             err);
+       /* Generate bio with pages pointing to the rdma buffer */
+       bio = rnbd_bio_map_kern(data, sess_dev->rnbd_dev->ibd_bio_set, datalen, GFP_KERNEL);
+       if (IS_ERR(bio)) {
+               rnbd_srv_err(sess_dev, "Failed to generate bio, err: %ld\n", PTR_ERR(bio));
                goto sess_dev_put;
        }
 
+       io = container_of(bio, struct rnbd_dev_blk_io, bio);
+       io->dev = sess_dev->rnbd_dev;
+       io->priv = priv;
+
+       bio->bi_end_io = rnbd_dev_bi_end_io;
+       bio->bi_private = io;
+       bio->bi_opf = rnbd_to_bio_flags(le32_to_cpu(msg->rw));
+       bio->bi_iter.bi_sector = le64_to_cpu(msg->sector);
+       bio->bi_iter.bi_size = le32_to_cpu(msg->bi_size);
+       prio = srv_sess->ver < RNBD_PROTO_VER_MAJOR ||
+              usrlen < sizeof(*msg) ? 0 : le16_to_cpu(msg->prio);
+       bio_set_prio(bio, prio);
+       bio_set_dev(bio, sess_dev->rnbd_dev->bdev);
+
+       submit_bio(bio);
+
        return 0;
 
 sess_dev_put:
index 87fe0b0..86f2e2d 100644 (file)
@@ -89,7 +89,12 @@ static int clk_pwm_probe(struct platform_device *pdev)
        }
 
        if (of_property_read_u32(node, "clock-frequency", &clk_pwm->fixed_rate))
-               clk_pwm->fixed_rate = NSEC_PER_SEC / pargs.period;
+               clk_pwm->fixed_rate = div64_u64(NSEC_PER_SEC, pargs.period);
+
+       if (!clk_pwm->fixed_rate) {
+               dev_err(&pdev->dev, "fixed_rate cannot be zero\n");
+               return -EINVAL;
+       }
 
        if (pargs.period != NSEC_PER_SEC / clk_pwm->fixed_rate &&
            pargs.period != DIV_ROUND_UP(NSEC_PER_SEC, clk_pwm->fixed_rate)) {
index 7c774ea..18564ef 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 obj-$(CONFIG_PMC_ATOM)         += clk-pmc-atom.o
-obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE)  += clk-st.o
+obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE)  += clk-fch.o
 clk-x86-lpss-objs              := clk-lpt.o
 obj-$(CONFIG_X86_INTEL_LPSS)   += clk-x86-lpss.o
 obj-$(CONFIG_CLK_LGM_CGU)      += clk-cgu.o clk-cgu-pll.o clk-lgm.o
diff --git a/drivers/clk/x86/clk-fch.c b/drivers/clk/x86/clk-fch.c
new file mode 100644 (file)
index 0000000..8f7c514
--- /dev/null
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: MIT
+/*
+ * clock framework for AMD Stoney based clocks
+ *
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/platform_data/clk-fch.h>
+#include <linux/platform_device.h>
+
+/* Clock Driving Strength 2 register */
+#define CLKDRVSTR2     0x28
+/* Clock Control 1 register */
+#define MISCCLKCNTL1   0x40
+/* Auxiliary clock1 enable bit */
+#define OSCCLKENB      2
+/* 25Mhz auxiliary output clock freq bit */
+#define OSCOUT1CLK25MHZ        16
+
+#define ST_CLK_48M     0
+#define ST_CLK_25M     1
+#define ST_CLK_MUX     2
+#define ST_CLK_GATE    3
+#define ST_MAX_CLKS    4
+
+#define RV_CLK_48M     0
+#define RV_CLK_GATE    1
+#define RV_MAX_CLKS    2
+
+static const char * const clk_oscout1_parents[] = { "clk48MHz", "clk25MHz" };
+static struct clk_hw *hws[ST_MAX_CLKS];
+
+static int fch_clk_probe(struct platform_device *pdev)
+{
+       struct fch_clk_data *fch_data;
+
+       fch_data = dev_get_platdata(&pdev->dev);
+       if (!fch_data || !fch_data->base)
+               return -EINVAL;
+
+       if (!fch_data->is_rv) {
+               hws[ST_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz",
+                       NULL, 0, 48000000);
+               hws[ST_CLK_25M] = clk_hw_register_fixed_rate(NULL, "clk25MHz",
+                       NULL, 0, 25000000);
+
+               hws[ST_CLK_MUX] = clk_hw_register_mux(NULL, "oscout1_mux",
+                       clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents),
+                       0, fch_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0,
+                       NULL);
+
+               clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_48M]->clk);
+
+               hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1",
+                       "oscout1_mux", 0, fch_data->base + MISCCLKCNTL1,
+                       OSCCLKENB, CLK_GATE_SET_TO_DISABLE, NULL);
+
+               devm_clk_hw_register_clkdev(&pdev->dev, hws[ST_CLK_GATE],
+                       "oscout1", NULL);
+       } else {
+               hws[RV_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz",
+                       NULL, 0, 48000000);
+
+               hws[RV_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1",
+                       "clk48MHz", 0, fch_data->base + MISCCLKCNTL1,
+                       OSCCLKENB, CLK_GATE_SET_TO_DISABLE, NULL);
+
+               devm_clk_hw_register_clkdev(&pdev->dev, hws[RV_CLK_GATE],
+                       "oscout1", NULL);
+       }
+
+       return 0;
+}
+
+static int fch_clk_remove(struct platform_device *pdev)
+{
+       int i, clks;
+       struct fch_clk_data *fch_data;
+
+       fch_data = dev_get_platdata(&pdev->dev);
+
+       clks = fch_data->is_rv ? RV_MAX_CLKS : ST_MAX_CLKS;
+
+       for (i = 0; i < clks; i++)
+               clk_hw_unregister(hws[i]);
+
+       return 0;
+}
+
+static struct platform_driver fch_clk_driver = {
+       .driver = {
+               .name = "clk-fch",
+               .suppress_bind_attrs = true,
+       },
+       .probe = fch_clk_probe,
+       .remove = fch_clk_remove,
+};
+builtin_platform_driver(fch_clk_driver);
diff --git a/drivers/clk/x86/clk-st.c b/drivers/clk/x86/clk-st.c
deleted file mode 100644 (file)
index 25d4b97..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// SPDX-License-Identifier: MIT
-/*
- * clock framework for AMD Stoney based clocks
- *
- * Copyright 2018 Advanced Micro Devices, Inc.
- */
-
-#include <linux/clk.h>
-#include <linux/clkdev.h>
-#include <linux/clk-provider.h>
-#include <linux/platform_data/clk-st.h>
-#include <linux/platform_device.h>
-
-/* Clock Driving Strength 2 register */
-#define CLKDRVSTR2     0x28
-/* Clock Control 1 register */
-#define MISCCLKCNTL1   0x40
-/* Auxiliary clock1 enable bit */
-#define OSCCLKENB      2
-/* 25Mhz auxiliary output clock freq bit */
-#define OSCOUT1CLK25MHZ        16
-
-#define ST_CLK_48M     0
-#define ST_CLK_25M     1
-#define ST_CLK_MUX     2
-#define ST_CLK_GATE    3
-#define ST_MAX_CLKS    4
-
-static const char * const clk_oscout1_parents[] = { "clk48MHz", "clk25MHz" };
-static struct clk_hw *hws[ST_MAX_CLKS];
-
-static int st_clk_probe(struct platform_device *pdev)
-{
-       struct st_clk_data *st_data;
-
-       st_data = dev_get_platdata(&pdev->dev);
-       if (!st_data || !st_data->base)
-               return -EINVAL;
-
-       hws[ST_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz", NULL, 0,
-                                                    48000000);
-       hws[ST_CLK_25M] = clk_hw_register_fixed_rate(NULL, "clk25MHz", NULL, 0,
-                                                    25000000);
-
-       hws[ST_CLK_MUX] = clk_hw_register_mux(NULL, "oscout1_mux",
-               clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents),
-               0, st_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0, NULL);
-
-       clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_48M]->clk);
-
-       hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "oscout1_mux",
-               0, st_data->base + MISCCLKCNTL1, OSCCLKENB,
-               CLK_GATE_SET_TO_DISABLE, NULL);
-
-       devm_clk_hw_register_clkdev(&pdev->dev, hws[ST_CLK_GATE], "oscout1",
-                                   NULL);
-
-       return 0;
-}
-
-static int st_clk_remove(struct platform_device *pdev)
-{
-       int i;
-
-       for (i = 0; i < ST_MAX_CLKS; i++)
-               clk_hw_unregister(hws[i]);
-       return 0;
-}
-
-static struct platform_driver st_clk_driver = {
-       .driver = {
-               .name = "clk-st",
-               .suppress_bind_attrs = true,
-       },
-       .probe = st_clk_probe,
-       .remove = st_clk_remove,
-};
-builtin_platform_driver(st_clk_driver);
index 2ed8b43..3576ad7 100644 (file)
@@ -291,6 +291,10 @@ config CLKSRC_STM32
        select CLKSRC_MMIO
        select TIMER_OF
 
+config CLKSRC_STM32_LP
+       bool "Low power clocksource for STM32 SoCs"
+       depends on MFD_STM32_LPTIMER || COMPILE_TEST
+
 config CLKSRC_MPS2
        bool "Clocksource for MPS2 SoCs" if COMPILE_TEST
        depends on GENERIC_SCHED_CLOCK
index 3994e22..eaedb72 100644 (file)
@@ -45,6 +45,7 @@ obj-$(CONFIG_BCM_KONA_TIMER)  += bcm_kona_timer.o
 obj-$(CONFIG_CADENCE_TTC_TIMER)        += timer-cadence-ttc.o
 obj-$(CONFIG_CLKSRC_EFM32)     += timer-efm32.o
 obj-$(CONFIG_CLKSRC_STM32)     += timer-stm32.o
+obj-$(CONFIG_CLKSRC_STM32_LP)  += timer-stm32-lp.o
 obj-$(CONFIG_CLKSRC_EXYNOS_MCT)        += exynos_mct.o
 obj-$(CONFIG_CLKSRC_LPC32XX)   += timer-lpc32xx.o
 obj-$(CONFIG_CLKSRC_MPS2)      += mps2-timer.o
diff --git a/drivers/clocksource/timer-stm32-lp.c b/drivers/clocksource/timer-stm32-lp.c
new file mode 100644 (file)
index 0000000..db2841d
--- /dev/null
@@ -0,0 +1,221 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Authors: Benjamin Gaignard <benjamin.gaignard@st.com> for STMicroelectronics.
+ *         Pascal Paillet <p.paillet@st.com> for STMicroelectronics.
+ */
+
+#include <linux/clk.h>
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/stm32-lptimer.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_wakeirq.h>
+
+#define CFGR_PSC_OFFSET                9
+#define STM32_LP_RATING                1000
+#define STM32_TARGET_CLKRATE   (32000 * HZ)
+#define STM32_LP_MAX_PSC       7
+
+struct stm32_lp_private {
+       struct regmap *reg;
+       struct clock_event_device clkevt;
+       unsigned long period;
+       struct device *dev;
+};
+
+static struct stm32_lp_private*
+to_priv(struct clock_event_device *clkevt)
+{
+       return container_of(clkevt, struct stm32_lp_private, clkevt);
+}
+
+static int stm32_clkevent_lp_shutdown(struct clock_event_device *clkevt)
+{
+       struct stm32_lp_private *priv = to_priv(clkevt);
+
+       regmap_write(priv->reg, STM32_LPTIM_CR, 0);
+       regmap_write(priv->reg, STM32_LPTIM_IER, 0);
+       /* clear pending flags */
+       regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_ARRMCF);
+
+       return 0;
+}
+
+static int stm32_clkevent_lp_set_timer(unsigned long evt,
+                                      struct clock_event_device *clkevt,
+                                      int is_periodic)
+{
+       struct stm32_lp_private *priv = to_priv(clkevt);
+
+       /* disable LPTIMER to be able to write into IER register*/
+       regmap_write(priv->reg, STM32_LPTIM_CR, 0);
+       /* enable ARR interrupt */
+       regmap_write(priv->reg, STM32_LPTIM_IER, STM32_LPTIM_ARRMIE);
+       /* enable LPTIMER to be able to write into ARR register */
+       regmap_write(priv->reg, STM32_LPTIM_CR, STM32_LPTIM_ENABLE);
+       /* set next event counter */
+       regmap_write(priv->reg, STM32_LPTIM_ARR, evt);
+
+       /* start counter */
+       if (is_periodic)
+               regmap_write(priv->reg, STM32_LPTIM_CR,
+                            STM32_LPTIM_CNTSTRT | STM32_LPTIM_ENABLE);
+       else
+               regmap_write(priv->reg, STM32_LPTIM_CR,
+                            STM32_LPTIM_SNGSTRT | STM32_LPTIM_ENABLE);
+
+       return 0;
+}
+
+static int stm32_clkevent_lp_set_next_event(unsigned long evt,
+                                           struct clock_event_device *clkevt)
+{
+       return stm32_clkevent_lp_set_timer(evt, clkevt,
+                                          clockevent_state_periodic(clkevt));
+}
+
+static int stm32_clkevent_lp_set_periodic(struct clock_event_device *clkevt)
+{
+       struct stm32_lp_private *priv = to_priv(clkevt);
+
+       return stm32_clkevent_lp_set_timer(priv->period, clkevt, true);
+}
+
+static int stm32_clkevent_lp_set_oneshot(struct clock_event_device *clkevt)
+{
+       struct stm32_lp_private *priv = to_priv(clkevt);
+
+       return stm32_clkevent_lp_set_timer(priv->period, clkevt, false);
+}
+
+static irqreturn_t stm32_clkevent_lp_irq_handler(int irq, void *dev_id)
+{
+       struct clock_event_device *clkevt = (struct clock_event_device *)dev_id;
+       struct stm32_lp_private *priv = to_priv(clkevt);
+
+       regmap_write(priv->reg, STM32_LPTIM_ICR, STM32_LPTIM_ARRMCF);
+
+       if (clkevt->event_handler)
+               clkevt->event_handler(clkevt);
+
+       return IRQ_HANDLED;
+}
+
+static void stm32_clkevent_lp_set_prescaler(struct stm32_lp_private *priv,
+                                           unsigned long *rate)
+{
+       int i;
+
+       for (i = 0; i <= STM32_LP_MAX_PSC; i++) {
+               if (DIV_ROUND_CLOSEST(*rate, 1 << i) < STM32_TARGET_CLKRATE)
+                       break;
+       }
+
+       regmap_write(priv->reg, STM32_LPTIM_CFGR, i << CFGR_PSC_OFFSET);
+
+       /* Adjust rate and period given the prescaler value */
+       *rate = DIV_ROUND_CLOSEST(*rate, (1 << i));
+       priv->period = DIV_ROUND_UP(*rate, HZ);
+}
+
+static void stm32_clkevent_lp_init(struct stm32_lp_private *priv,
+                                 struct device_node *np, unsigned long rate)
+{
+       priv->clkevt.name = np->full_name;
+       priv->clkevt.cpumask = cpu_possible_mask;
+       priv->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
+                               CLOCK_EVT_FEAT_ONESHOT;
+       priv->clkevt.set_state_shutdown = stm32_clkevent_lp_shutdown;
+       priv->clkevt.set_state_periodic = stm32_clkevent_lp_set_periodic;
+       priv->clkevt.set_state_oneshot = stm32_clkevent_lp_set_oneshot;
+       priv->clkevt.set_next_event = stm32_clkevent_lp_set_next_event;
+       priv->clkevt.rating = STM32_LP_RATING;
+
+       clockevents_config_and_register(&priv->clkevt, rate, 0x1,
+                                       STM32_LPTIM_MAX_ARR);
+}
+
+static int stm32_clkevent_lp_probe(struct platform_device *pdev)
+{
+       struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
+       struct stm32_lp_private *priv;
+       unsigned long rate;
+       int ret, irq;
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->reg = ddata->regmap;
+       ret = clk_prepare_enable(ddata->clk);
+       if (ret)
+               return -EINVAL;
+
+       rate = clk_get_rate(ddata->clk);
+       if (!rate) {
+               ret = -EINVAL;
+               goto out_clk_disable;
+       }
+
+       irq = platform_get_irq(to_platform_device(pdev->dev.parent), 0);
+       if (irq <= 0) {
+               ret = irq;
+               goto out_clk_disable;
+       }
+
+       if (of_property_read_bool(pdev->dev.parent->of_node, "wakeup-source")) {
+               ret = device_init_wakeup(&pdev->dev, true);
+               if (ret)
+                       goto out_clk_disable;
+
+               ret = dev_pm_set_wake_irq(&pdev->dev, irq);
+               if (ret)
+                       goto out_clk_disable;
+       }
+
+       ret = devm_request_irq(&pdev->dev, irq, stm32_clkevent_lp_irq_handler,
+                              IRQF_TIMER, pdev->name, &priv->clkevt);
+       if (ret)
+               goto out_clk_disable;
+
+       stm32_clkevent_lp_set_prescaler(priv, &rate);
+
+       stm32_clkevent_lp_init(priv, pdev->dev.parent->of_node, rate);
+
+       priv->dev = &pdev->dev;
+
+       return 0;
+
+out_clk_disable:
+       clk_disable_unprepare(ddata->clk);
+       return ret;
+}
+
+static int stm32_clkevent_lp_remove(struct platform_device *pdev)
+{
+       return -EBUSY; /* cannot unregister clockevent */
+}
+
+static const struct of_device_id stm32_clkevent_lp_of_match[] = {
+       { .compatible = "st,stm32-lptimer-timer", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, stm32_clkevent_lp_of_match);
+
+static struct platform_driver stm32_clkevent_lp_driver = {
+       .probe  = stm32_clkevent_lp_probe,
+       .remove = stm32_clkevent_lp_remove,
+       .driver = {
+               .name = "stm32-lptimer-timer",
+               .of_match_table = of_match_ptr(stm32_clkevent_lp_of_match),
+       },
+};
+module_platform_driver(stm32_clkevent_lp_driver);
+
+MODULE_ALIAS("platform:stm32-lptimer-timer");
+MODULE_DESCRIPTION("STMicroelectronics STM32 clockevent low power driver");
+MODULE_LICENSE("GPL v2");
index afad06b..02ab56b 100644 (file)
@@ -73,8 +73,6 @@ static inline bool has_target(void)
 static unsigned int __cpufreq_get(struct cpufreq_policy *policy);
 static int cpufreq_init_governor(struct cpufreq_policy *policy);
 static void cpufreq_exit_governor(struct cpufreq_policy *policy);
-static int cpufreq_start_governor(struct cpufreq_policy *policy);
-static void cpufreq_stop_governor(struct cpufreq_policy *policy);
 static void cpufreq_governor_limits(struct cpufreq_policy *policy);
 static int cpufreq_set_policy(struct cpufreq_policy *policy,
                              struct cpufreq_governor *new_gov,
@@ -2266,7 +2264,7 @@ static void cpufreq_exit_governor(struct cpufreq_policy *policy)
        module_put(policy->governor->owner);
 }
 
-static int cpufreq_start_governor(struct cpufreq_policy *policy)
+int cpufreq_start_governor(struct cpufreq_policy *policy)
 {
        int ret;
 
@@ -2293,7 +2291,7 @@ static int cpufreq_start_governor(struct cpufreq_policy *policy)
        return 0;
 }
 
-static void cpufreq_stop_governor(struct cpufreq_policy *policy)
+void cpufreq_stop_governor(struct cpufreq_policy *policy)
 {
        if (cpufreq_suspended || !policy->governor)
                return;
index fc459c9..e0220a6 100644 (file)
@@ -36,6 +36,7 @@
 #define INTEL_PSTATE_SAMPLING_INTERVAL (10 * NSEC_PER_MSEC)
 
 #define INTEL_CPUFREQ_TRANSITION_LATENCY       20000
+#define INTEL_CPUFREQ_TRANSITION_DELAY_HWP     5000
 #define INTEL_CPUFREQ_TRANSITION_DELAY         500
 
 #ifdef CONFIG_ACPI
@@ -220,6 +221,7 @@ struct global_params {
  *                     preference/bias
  * @epp_saved:         Saved EPP/EPB during system suspend or CPU offline
  *                     operation
+ * @epp_cached         Cached HWP energy-performance preference value
  * @hwp_req_cached:    Cached value of the last HWP Request MSR
  * @hwp_cap_cached:    Cached value of the last HWP Capabilities MSR
  * @last_io_update:    Last time when IO wake flag was set
@@ -257,6 +259,7 @@ struct cpudata {
        s16 epp_policy;
        s16 epp_default;
        s16 epp_saved;
+       s16 epp_cached;
        u64 hwp_req_cached;
        u64 hwp_cap_cached;
        u64 last_io_update;
@@ -639,6 +642,26 @@ static int intel_pstate_get_energy_pref_index(struct cpudata *cpu_data, int *raw
        return index;
 }
 
+static int intel_pstate_set_epp(struct cpudata *cpu, u32 epp)
+{
+       /*
+        * Use the cached HWP Request MSR value, because in the active mode the
+        * register itself may be updated by intel_pstate_hwp_boost_up() or
+        * intel_pstate_hwp_boost_down() at any time.
+        */
+       u64 value = READ_ONCE(cpu->hwp_req_cached);
+
+       value &= ~GENMASK_ULL(31, 24);
+       value |= (u64)epp << 24;
+       /*
+        * The only other updater of hwp_req_cached in the active mode,
+        * intel_pstate_hwp_set(), is called under the same lock as this
+        * function, so it cannot run in parallel with the update below.
+        */
+       WRITE_ONCE(cpu->hwp_req_cached, value);
+       return wrmsrl_on_cpu(cpu->cpu, MSR_HWP_REQUEST, value);
+}
+
 static int intel_pstate_set_energy_pref_index(struct cpudata *cpu_data,
                                              int pref_index, bool use_raw,
                                              u32 raw_epp)
@@ -650,28 +673,12 @@ static int intel_pstate_set_energy_pref_index(struct cpudata *cpu_data,
                epp = cpu_data->epp_default;
 
        if (boot_cpu_has(X86_FEATURE_HWP_EPP)) {
-               /*
-                * Use the cached HWP Request MSR value, because the register
-                * itself may be updated by intel_pstate_hwp_boost_up() or
-                * intel_pstate_hwp_boost_down() at any time.
-                */
-               u64 value = READ_ONCE(cpu_data->hwp_req_cached);
-
-               value &= ~GENMASK_ULL(31, 24);
-
                if (use_raw)
                        epp = raw_epp;
                else if (epp == -EINVAL)
                        epp = epp_values[pref_index - 1];
 
-               value |= (u64)epp << 24;
-               /*
-                * The only other updater of hwp_req_cached in the active mode,
-                * intel_pstate_hwp_set(), is called under the same lock as this
-                * function, so it cannot run in parallel with the update below.
-                */
-               WRITE_ONCE(cpu_data->hwp_req_cached, value);
-               ret = wrmsrl_on_cpu(cpu_data->cpu, MSR_HWP_REQUEST, value);
+               ret = intel_pstate_set_epp(cpu_data, epp);
        } else {
                if (epp == -EINVAL)
                        epp = (pref_index - 1) << 2;
@@ -697,10 +704,12 @@ static ssize_t show_energy_performance_available_preferences(
 
 cpufreq_freq_attr_ro(energy_performance_available_preferences);
 
+static struct cpufreq_driver intel_pstate;
+
 static ssize_t store_energy_performance_preference(
                struct cpufreq_policy *policy, const char *buf, size_t count)
 {
-       struct cpudata *cpu_data = all_cpu_data[policy->cpu];
+       struct cpudata *cpu = all_cpu_data[policy->cpu];
        char str_preference[21];
        bool raw = false;
        ssize_t ret;
@@ -725,15 +734,44 @@ static ssize_t store_energy_performance_preference(
                raw = true;
        }
 
+       /*
+        * This function runs with the policy R/W semaphore held, which
+        * guarantees that the driver pointer will not change while it is
+        * running.
+        */
+       if (!intel_pstate_driver)
+               return -EAGAIN;
+
        mutex_lock(&intel_pstate_limits_lock);
 
-       ret = intel_pstate_set_energy_pref_index(cpu_data, ret, raw, epp);
-       if (!ret)
-               ret = count;
+       if (intel_pstate_driver == &intel_pstate) {
+               ret = intel_pstate_set_energy_pref_index(cpu, ret, raw, epp);
+       } else {
+               /*
+                * In the passive mode the governor needs to be stopped on the
+                * target CPU before the EPP update and restarted after it,
+                * which is super-heavy-weight, so make sure it is worth doing
+                * upfront.
+                */
+               if (!raw)
+                       epp = ret ? epp_values[ret - 1] : cpu->epp_default;
+
+               if (cpu->epp_cached != epp) {
+                       int err;
+
+                       cpufreq_stop_governor(policy);
+                       ret = intel_pstate_set_epp(cpu, epp);
+                       err = cpufreq_start_governor(policy);
+                       if (!ret) {
+                               cpu->epp_cached = epp;
+                               ret = err;
+                       }
+               }
+       }
 
        mutex_unlock(&intel_pstate_limits_lock);
 
-       return ret;
+       return ret ?: count;
 }
 
 static ssize_t show_energy_performance_preference(
@@ -1145,8 +1183,6 @@ static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b,
        return count;
 }
 
-static struct cpufreq_driver intel_pstate;
-
 static void update_qos_request(enum freq_qos_req_type type)
 {
        int max_state, turbo_max, freq, i, perf_pct;
@@ -1330,9 +1366,10 @@ static const struct attribute_group intel_pstate_attr_group = {
 
 static const struct x86_cpu_id intel_pstate_cpu_ee_disable_ids[];
 
+static struct kobject *intel_pstate_kobject;
+
 static void __init intel_pstate_sysfs_expose_params(void)
 {
-       struct kobject *intel_pstate_kobject;
        int rc;
 
        intel_pstate_kobject = kobject_create_and_add("intel_pstate",
@@ -1357,17 +1394,31 @@ static void __init intel_pstate_sysfs_expose_params(void)
        rc = sysfs_create_file(intel_pstate_kobject, &min_perf_pct.attr);
        WARN_ON(rc);
 
-       if (hwp_active) {
-               rc = sysfs_create_file(intel_pstate_kobject,
-                                      &hwp_dynamic_boost.attr);
-               WARN_ON(rc);
-       }
-
        if (x86_match_cpu(intel_pstate_cpu_ee_disable_ids)) {
                rc = sysfs_create_file(intel_pstate_kobject, &energy_efficiency.attr);
                WARN_ON(rc);
        }
 }
+
+static void intel_pstate_sysfs_expose_hwp_dynamic_boost(void)
+{
+       int rc;
+
+       if (!hwp_active)
+               return;
+
+       rc = sysfs_create_file(intel_pstate_kobject, &hwp_dynamic_boost.attr);
+       WARN_ON_ONCE(rc);
+}
+
+static void intel_pstate_sysfs_hide_hwp_dynamic_boost(void)
+{
+       if (!hwp_active)
+               return;
+
+       sysfs_remove_file(intel_pstate_kobject, &hwp_dynamic_boost.attr);
+}
+
 /************************** sysfs end ************************/
 
 static void intel_pstate_hwp_enable(struct cpudata *cpudata)
@@ -2247,7 +2298,10 @@ static int intel_pstate_verify_policy(struct cpufreq_policy_data *policy)
 
 static void intel_cpufreq_stop_cpu(struct cpufreq_policy *policy)
 {
-       intel_pstate_set_min_pstate(all_cpu_data[policy->cpu]);
+       if (hwp_active)
+               intel_pstate_hwp_force_min_perf(policy->cpu);
+       else
+               intel_pstate_set_min_pstate(all_cpu_data[policy->cpu]);
 }
 
 static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
@@ -2255,12 +2309,10 @@ static void intel_pstate_stop_cpu(struct cpufreq_policy *policy)
        pr_debug("CPU %d exiting\n", policy->cpu);
 
        intel_pstate_clear_update_util_hook(policy->cpu);
-       if (hwp_active) {
+       if (hwp_active)
                intel_pstate_hwp_save_state(policy);
-               intel_pstate_hwp_force_min_perf(policy->cpu);
-       } else {
-               intel_cpufreq_stop_cpu(policy);
-       }
+
+       intel_cpufreq_stop_cpu(policy);
 }
 
 static int intel_pstate_cpu_exit(struct cpufreq_policy *policy)
@@ -2390,13 +2442,71 @@ static void intel_cpufreq_trace(struct cpudata *cpu, unsigned int trace_type, in
                fp_toint(cpu->iowait_boost * 100));
 }
 
+static void intel_cpufreq_adjust_hwp(struct cpudata *cpu, u32 target_pstate,
+                                    bool fast_switch)
+{
+       u64 prev = READ_ONCE(cpu->hwp_req_cached), value = prev;
+
+       value &= ~HWP_MIN_PERF(~0L);
+       value |= HWP_MIN_PERF(target_pstate);
+
+       /*
+        * The entire MSR needs to be updated in order to update the HWP min
+        * field in it, so opportunistically update the max too if needed.
+        */
+       value &= ~HWP_MAX_PERF(~0L);
+       value |= HWP_MAX_PERF(cpu->max_perf_ratio);
+
+       if (value == prev)
+               return;
+
+       WRITE_ONCE(cpu->hwp_req_cached, value);
+       if (fast_switch)
+               wrmsrl(MSR_HWP_REQUEST, value);
+       else
+               wrmsrl_on_cpu(cpu->cpu, MSR_HWP_REQUEST, value);
+}
+
+static void intel_cpufreq_adjust_perf_ctl(struct cpudata *cpu,
+                                         u32 target_pstate, bool fast_switch)
+{
+       if (fast_switch)
+               wrmsrl(MSR_IA32_PERF_CTL,
+                      pstate_funcs.get_val(cpu, target_pstate));
+       else
+               wrmsrl_on_cpu(cpu->cpu, MSR_IA32_PERF_CTL,
+                             pstate_funcs.get_val(cpu, target_pstate));
+}
+
+static int intel_cpufreq_update_pstate(struct cpudata *cpu, int target_pstate,
+                                      bool fast_switch)
+{
+       int old_pstate = cpu->pstate.current_pstate;
+
+       target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
+       if (target_pstate != old_pstate) {
+               cpu->pstate.current_pstate = target_pstate;
+               if (hwp_active)
+                       intel_cpufreq_adjust_hwp(cpu, target_pstate,
+                                                fast_switch);
+               else
+                       intel_cpufreq_adjust_perf_ctl(cpu, target_pstate,
+                                                     fast_switch);
+       }
+
+       intel_cpufreq_trace(cpu, fast_switch ? INTEL_PSTATE_TRACE_FAST_SWITCH :
+                           INTEL_PSTATE_TRACE_TARGET, old_pstate);
+
+       return target_pstate;
+}
+
 static int intel_cpufreq_target(struct cpufreq_policy *policy,
                                unsigned int target_freq,
                                unsigned int relation)
 {
        struct cpudata *cpu = all_cpu_data[policy->cpu];
        struct cpufreq_freqs freqs;
-       int target_pstate, old_pstate;
+       int target_pstate;
 
        update_turbo_state();
 
@@ -2404,6 +2514,7 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy,
        freqs.new = target_freq;
 
        cpufreq_freq_transition_begin(policy, &freqs);
+
        switch (relation) {
        case CPUFREQ_RELATION_L:
                target_pstate = DIV_ROUND_UP(freqs.new, cpu->pstate.scaling);
@@ -2415,15 +2526,11 @@ static int intel_cpufreq_target(struct cpufreq_policy *policy,
                target_pstate = DIV_ROUND_CLOSEST(freqs.new, cpu->pstate.scaling);
                break;
        }
-       target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
-       old_pstate = cpu->pstate.current_pstate;
-       if (target_pstate != cpu->pstate.current_pstate) {
-               cpu->pstate.current_pstate = target_pstate;
-               wrmsrl_on_cpu(policy->cpu, MSR_IA32_PERF_CTL,
-                             pstate_funcs.get_val(cpu, target_pstate));
-       }
+
+       target_pstate = intel_cpufreq_update_pstate(cpu, target_pstate, false);
+
        freqs.new = target_pstate * cpu->pstate.scaling;
-       intel_cpufreq_trace(cpu, INTEL_PSTATE_TRACE_TARGET, old_pstate);
+
        cpufreq_freq_transition_end(policy, &freqs, false);
 
        return 0;
@@ -2433,15 +2540,14 @@ static unsigned int intel_cpufreq_fast_switch(struct cpufreq_policy *policy,
                                              unsigned int target_freq)
 {
        struct cpudata *cpu = all_cpu_data[policy->cpu];
-       int target_pstate, old_pstate;
+       int target_pstate;
 
        update_turbo_state();
 
        target_pstate = DIV_ROUND_UP(target_freq, cpu->pstate.scaling);
-       target_pstate = intel_pstate_prepare_request(cpu, target_pstate);
-       old_pstate = cpu->pstate.current_pstate;
-       intel_pstate_update_pstate(cpu, target_pstate);
-       intel_cpufreq_trace(cpu, INTEL_PSTATE_TRACE_FAST_SWITCH, old_pstate);
+
+       target_pstate = intel_cpufreq_update_pstate(cpu, target_pstate, true);
+
        return target_pstate * cpu->pstate.scaling;
 }
 
@@ -2461,7 +2567,6 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy)
                return ret;
 
        policy->cpuinfo.transition_latency = INTEL_CPUFREQ_TRANSITION_LATENCY;
-       policy->transition_delay_us = INTEL_CPUFREQ_TRANSITION_DELAY;
        /* This reflects the intel_pstate_get_cpu_pstates() setting. */
        policy->cur = policy->cpuinfo.min_freq;
 
@@ -2473,10 +2578,18 @@ static int intel_cpufreq_cpu_init(struct cpufreq_policy *policy)
 
        cpu = all_cpu_data[policy->cpu];
 
-       if (hwp_active)
+       if (hwp_active) {
+               u64 value;
+
                intel_pstate_get_hwp_max(policy->cpu, &turbo_max, &max_state);
-       else
+               policy->transition_delay_us = INTEL_CPUFREQ_TRANSITION_DELAY_HWP;
+               rdmsrl_on_cpu(cpu->cpu, MSR_HWP_REQUEST, &value);
+               WRITE_ONCE(cpu->hwp_req_cached, value);
+               cpu->epp_cached = (value & GENMASK_ULL(31, 24)) >> 24;
+       } else {
                turbo_max = cpu->pstate.turbo_pstate;
+               policy->transition_delay_us = INTEL_CPUFREQ_TRANSITION_DELAY;
+       }
 
        min_freq = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100);
        min_freq *= cpu->pstate.scaling;
@@ -2553,6 +2666,10 @@ static void intel_pstate_driver_cleanup(void)
                }
        }
        put_online_cpus();
+
+       if (intel_pstate_driver == &intel_pstate)
+               intel_pstate_sysfs_hide_hwp_dynamic_boost();
+
        intel_pstate_driver = NULL;
 }
 
@@ -2560,6 +2677,9 @@ static int intel_pstate_register_driver(struct cpufreq_driver *driver)
 {
        int ret;
 
+       if (driver == &intel_pstate)
+               intel_pstate_sysfs_expose_hwp_dynamic_boost();
+
        memset(&global, 0, sizeof(global));
        global.max_perf_pct = 100;
 
@@ -2577,9 +2697,6 @@ static int intel_pstate_register_driver(struct cpufreq_driver *driver)
 
 static int intel_pstate_unregister_driver(void)
 {
-       if (hwp_active)
-               return -EBUSY;
-
        cpufreq_unregister_driver(intel_pstate_driver);
        intel_pstate_driver_cleanup();
 
@@ -2835,7 +2952,10 @@ static int __init intel_pstate_init(void)
                        hwp_active++;
                        hwp_mode_bdw = id->driver_data;
                        intel_pstate.attr = hwp_cpufreq_attrs;
-                       default_driver = &intel_pstate;
+                       intel_cpufreq.attr = hwp_cpufreq_attrs;
+                       if (!default_driver)
+                               default_driver = &intel_pstate;
+
                        goto hwp_cpu_matched;
                }
        } else {
@@ -2906,14 +3026,13 @@ static int __init intel_pstate_setup(char *str)
        if (!str)
                return -EINVAL;
 
-       if (!strcmp(str, "disable")) {
+       if (!strcmp(str, "disable"))
                no_load = 1;
-       } else if (!strcmp(str, "active")) {
+       else if (!strcmp(str, "active"))
                default_driver = &intel_pstate;
-       } else if (!strcmp(str, "passive")) {
+       else if (!strcmp(str, "passive"))
                default_driver = &intel_cpufreq;
-               no_hwp = 1;
-       }
+
        if (!strcmp(str, "no_hwp")) {
                pr_info("HWP disabled\n");
                no_hwp = 1;
index d68346a..ebe5099 100644 (file)
        (n << (28 + (2 * skl) - PAGE_SHIFT))
 
 static int nr_channels;
+static struct pci_dev *mci_pdev;
+static int ie31200_registered = 1;
 
 struct ie31200_priv {
        void __iomem *window;
@@ -538,12 +540,16 @@ fail_free:
 static int ie31200_init_one(struct pci_dev *pdev,
                            const struct pci_device_id *ent)
 {
-       edac_dbg(0, "MC:\n");
+       int rc;
 
+       edac_dbg(0, "MC:\n");
        if (pci_enable_device(pdev) < 0)
                return -EIO;
+       rc = ie31200_probe1(pdev, ent->driver_data);
+       if (rc == 0 && !mci_pdev)
+               mci_pdev = pci_dev_get(pdev);
 
-       return ie31200_probe1(pdev, ent->driver_data);
+       return rc;
 }
 
 static void ie31200_remove_one(struct pci_dev *pdev)
@@ -552,6 +558,8 @@ static void ie31200_remove_one(struct pci_dev *pdev)
        struct ie31200_priv *priv;
 
        edac_dbg(0, "\n");
+       pci_dev_put(mci_pdev);
+       mci_pdev = NULL;
        mci = edac_mc_del_mc(&pdev->dev);
        if (!mci)
                return;
@@ -593,17 +601,53 @@ static struct pci_driver ie31200_driver = {
 
 static int __init ie31200_init(void)
 {
+       int pci_rc, i;
+
        edac_dbg(3, "MC:\n");
        /* Ensure that the OPSTATE is set correctly for POLL or NMI */
        opstate_init();
 
-       return pci_register_driver(&ie31200_driver);
+       pci_rc = pci_register_driver(&ie31200_driver);
+       if (pci_rc < 0)
+               goto fail0;
+
+       if (!mci_pdev) {
+               ie31200_registered = 0;
+               for (i = 0; ie31200_pci_tbl[i].vendor != 0; i++) {
+                       mci_pdev = pci_get_device(ie31200_pci_tbl[i].vendor,
+                                                 ie31200_pci_tbl[i].device,
+                                                 NULL);
+                       if (mci_pdev)
+                               break;
+               }
+               if (!mci_pdev) {
+                       edac_dbg(0, "ie31200 pci_get_device fail\n");
+                       pci_rc = -ENODEV;
+                       goto fail1;
+               }
+               pci_rc = ie31200_init_one(mci_pdev, &ie31200_pci_tbl[i]);
+               if (pci_rc < 0) {
+                       edac_dbg(0, "ie31200 init fail\n");
+                       pci_rc = -ENODEV;
+                       goto fail1;
+               }
+       }
+       return 0;
+
+fail1:
+       pci_unregister_driver(&ie31200_driver);
+fail0:
+       pci_dev_put(mci_pdev);
+
+       return pci_rc;
 }
 
 static void __exit ie31200_exit(void)
 {
        edac_dbg(3, "MC:\n");
        pci_unregister_driver(&ie31200_driver);
+       if (!ie31200_registered)
+               ie31200_remove_one(mci_pdev);
 }
 
 module_init(ie31200_init);
index aaed9eb..bbde3b1 100644 (file)
@@ -1929,7 +1929,7 @@ static int pwm_setup_backlight(struct intel_connector *connector,
                return retval;
        }
 
-       level = DIV_ROUND_UP(pwm_get_duty_cycle(panel->backlight.pwm) * 100,
+       level = DIV_ROUND_UP_ULL(pwm_get_duty_cycle(panel->backlight.pwm) * 100,
                             CRC_PMIC_PWM_PERIOD_NS);
        panel->backlight.level =
                intel_panel_compute_brightness(connector, level);
index 3e660fb..013c9e0 100644 (file)
@@ -157,7 +157,8 @@ int xen_drm_front_mode_set(struct xen_drm_front_drm_pipeline *pipeline,
 
 int xen_drm_front_dbuf_create(struct xen_drm_front_info *front_info,
                              u64 dbuf_cookie, u32 width, u32 height,
-                             u32 bpp, u64 size, struct page **pages)
+                             u32 bpp, u64 size, u32 offset,
+                             struct page **pages)
 {
        struct xen_drm_front_evtchnl *evtchnl;
        struct xen_drm_front_dbuf *dbuf;
@@ -194,6 +195,7 @@ int xen_drm_front_dbuf_create(struct xen_drm_front_info *front_info,
        req->op.dbuf_create.gref_directory =
                        xen_front_pgdir_shbuf_get_dir_start(&dbuf->shbuf);
        req->op.dbuf_create.buffer_sz = size;
+       req->op.dbuf_create.data_ofs = offset;
        req->op.dbuf_create.dbuf_cookie = dbuf_cookie;
        req->op.dbuf_create.width = width;
        req->op.dbuf_create.height = height;
@@ -400,15 +402,15 @@ static int xen_drm_drv_dumb_create(struct drm_file *filp,
        args->size = args->pitch * args->height;
 
        obj = xen_drm_front_gem_create(dev, args->size);
-       if (IS_ERR_OR_NULL(obj)) {
-               ret = PTR_ERR_OR_ZERO(obj);
+       if (IS_ERR(obj)) {
+               ret = PTR_ERR(obj);
                goto fail;
        }
 
        ret = xen_drm_front_dbuf_create(drm_info->front_info,
                                        xen_drm_front_dbuf_to_cookie(obj),
                                        args->width, args->height, args->bpp,
-                                       args->size,
+                                       args->size, 0,
                                        xen_drm_front_gem_get_pages(obj));
        if (ret)
                goto fail_backend;
index f92c258..54486d8 100644 (file)
@@ -145,7 +145,7 @@ int xen_drm_front_mode_set(struct xen_drm_front_drm_pipeline *pipeline,
 
 int xen_drm_front_dbuf_create(struct xen_drm_front_info *front_info,
                              u64 dbuf_cookie, u32 width, u32 height,
-                             u32 bpp, u64 size, struct page **pages);
+                             u32 bpp, u64 size, u32 offset, struct page **pages);
 
 int xen_drm_front_fb_attach(struct xen_drm_front_info *front_info,
                            u64 dbuf_cookie, u64 fb_cookie, u32 width,
index 459702f..44f1f70 100644 (file)
@@ -33,6 +33,7 @@ static const u32 plane_formats[] = {
        DRM_FORMAT_ARGB4444,
        DRM_FORMAT_XRGB1555,
        DRM_FORMAT_ARGB1555,
+       DRM_FORMAT_YUYV,
 };
 
 const u32 *xen_drm_front_conn_get_formats(int *format_count)
index f0b85e0..39ff95b 100644 (file)
@@ -83,7 +83,7 @@ static struct xen_gem_object *gem_create(struct drm_device *dev, size_t size)
 
        size = round_up(size, PAGE_SIZE);
        xen_obj = gem_create_obj(dev, size);
-       if (IS_ERR_OR_NULL(xen_obj))
+       if (IS_ERR(xen_obj))
                return xen_obj;
 
        if (drm_info->front_info->cfg.be_alloc) {
@@ -117,7 +117,7 @@ static struct xen_gem_object *gem_create(struct drm_device *dev, size_t size)
         */
        xen_obj->num_pages = DIV_ROUND_UP(size, PAGE_SIZE);
        xen_obj->pages = drm_gem_get_pages(&xen_obj->base);
-       if (IS_ERR_OR_NULL(xen_obj->pages)) {
+       if (IS_ERR(xen_obj->pages)) {
                ret = PTR_ERR(xen_obj->pages);
                xen_obj->pages = NULL;
                goto fail;
@@ -136,7 +136,7 @@ struct drm_gem_object *xen_drm_front_gem_create(struct drm_device *dev,
        struct xen_gem_object *xen_obj;
 
        xen_obj = gem_create(dev, size);
-       if (IS_ERR_OR_NULL(xen_obj))
+       if (IS_ERR(xen_obj))
                return ERR_CAST(xen_obj);
 
        return &xen_obj->base;
@@ -194,7 +194,7 @@ xen_drm_front_gem_import_sg_table(struct drm_device *dev,
 
        size = attach->dmabuf->size;
        xen_obj = gem_create_obj(dev, size);
-       if (IS_ERR_OR_NULL(xen_obj))
+       if (IS_ERR(xen_obj))
                return ERR_CAST(xen_obj);
 
        ret = gem_alloc_pages_array(xen_obj, size);
@@ -210,7 +210,8 @@ xen_drm_front_gem_import_sg_table(struct drm_device *dev,
 
        ret = xen_drm_front_dbuf_create(drm_info->front_info,
                                        xen_drm_front_dbuf_to_cookie(&xen_obj->base),
-                                       0, 0, 0, size, xen_obj->pages);
+                                       0, 0, 0, size, sgt->sgl->offset,
+                                       xen_obj->pages);
        if (ret < 0)
                return ERR_PTR(ret);
 
index 78096bb..ef11b1e 100644 (file)
@@ -60,7 +60,7 @@ fb_create(struct drm_device *dev, struct drm_file *filp,
        int ret;
 
        fb = drm_gem_fb_create_with_funcs(dev, filp, mode_cmd, &fb_funcs);
-       if (IS_ERR_OR_NULL(fb))
+       if (IS_ERR(fb))
                return fb;
 
        gem_obj = fb->obj[0];
index b50081c..910b6e9 100644 (file)
@@ -86,6 +86,10 @@ static int hyperv_die_event(struct notifier_block *nb, unsigned long val,
        struct die_args *die = (struct die_args *)args;
        struct pt_regs *regs = die->regs;
 
+       /* Don't notify Hyper-V if the die event is other than oops */
+       if (val != DIE_OOPS)
+               return NOTIFY_DONE;
+
        /*
         * Hyper-V should be notified only once about a panic.  If we will be
         * doing hyperv_report_panic_msg() later with kmsg data, don't do
index 30b7b3e..17bb642 100644 (file)
@@ -447,7 +447,7 @@ static int pwm_fan_resume(struct device *dev)
                return 0;
 
        pwm_get_args(ctx->pwm, &pargs);
-       duty = DIV_ROUND_UP(ctx->pwm_value * (pargs.period - 1), MAX_PWM);
+       duty = DIV_ROUND_UP_ULL(ctx->pwm_value * (pargs.period - 1), MAX_PWM);
        ret = pwm_config(ctx->pwm, duty, pargs.period);
        if (ret)
                return ret;
index a71bc58..0dfeb2d 100644 (file)
@@ -55,6 +55,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
        { "HISI02A1", 0 },
        { "HISI02A2", 0 },
        { "HISI02A3", 0 },
+       { "HYGO0010", ACCESS_INTR_MASK },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
index da0bf85..64590b8 100644 (file)
@@ -21,8 +21,6 @@
 #elif defined(__arm__)
 /* defined in include/asm-arm/arch-xxx/irqs.h */
 #include <asm/irq.h>
-#elif defined(CONFIG_SH_CAYMAN)
-#include <asm/irq.h>
 #elif defined(CONFIG_PPC)
 extern int of_i8042_kbd_irq;
 extern int of_i8042_aux_irq;
index c10a931..53945ca 100644 (file)
@@ -679,7 +679,7 @@ pdc_receive(struct pdc_state *pdcs)
 
        /* read last_rx_curr from register once */
        pdcs->last_rx_curr =
-           (ioread32(&pdcs->rxregs_64->status0) &
+           (ioread32((const void __iomem *)&pdcs->rxregs_64->status0) &
             CRYPTO_D64_RS0_CD_MASK) / RING_ENTRY_SIZE;
 
        do {
index 73fd50e..d50737e 100644 (file)
@@ -1139,6 +1139,7 @@ static int resize_bitmaps(struct mddev *mddev, sector_t newsize, sector_t oldsiz
                bitmap = get_bitmap_from_slot(mddev, i);
                if (IS_ERR(bitmap)) {
                        pr_err("can't get bitmap from slot %d\n", i);
+                       bitmap = NULL;
                        goto out;
                }
                counts = &bitmap->counts;
index 15bbdc1..6072782 100644 (file)
@@ -850,7 +850,13 @@ void mddev_unlock(struct mddev *mddev)
                                sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
                                if (mddev->sysfs_action)
                                        sysfs_put(mddev->sysfs_action);
+                               if (mddev->sysfs_completed)
+                                       sysfs_put(mddev->sysfs_completed);
+                               if (mddev->sysfs_degraded)
+                                       sysfs_put(mddev->sysfs_degraded);
                                mddev->sysfs_action = NULL;
+                               mddev->sysfs_completed = NULL;
+                               mddev->sysfs_degraded = NULL;
                        }
                }
                mddev->sysfs_active = 0;
@@ -4068,6 +4074,8 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
                        pr_warn("md: cannot register extra attributes for %s\n",
                                mdname(mddev));
                mddev->sysfs_action = sysfs_get_dirent(mddev->kobj.sd, "sync_action");
+               mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed");
+               mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");
        }
        if (oldpers->sync_request != NULL &&
            pers->sync_request == NULL) {
@@ -5582,14 +5590,9 @@ static void md_free(struct kobject *ko)
 
        if (mddev->sysfs_state)
                sysfs_put(mddev->sysfs_state);
-       if (mddev->sysfs_completed)
-               sysfs_put(mddev->sysfs_completed);
-       if (mddev->sysfs_degraded)
-               sysfs_put(mddev->sysfs_degraded);
        if (mddev->sysfs_level)
                sysfs_put(mddev->sysfs_level);
 
-
        if (mddev->gendisk)
                del_gendisk(mddev->gendisk);
        if (mddev->queue)
@@ -5757,8 +5760,6 @@ static int md_alloc(dev_t dev, char *name)
        if (!error && mddev->kobj.sd) {
                kobject_uevent(&mddev->kobj, KOBJ_ADD);
                mddev->sysfs_state = sysfs_get_dirent_safe(mddev->kobj.sd, "array_state");
-               mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed");
-               mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");
                mddev->sysfs_level = sysfs_get_dirent_safe(mddev->kobj.sd, "level");
        }
        mddev_put(mddev);
@@ -6036,6 +6037,8 @@ int md_run(struct mddev *mddev)
                        pr_warn("md: cannot register extra attributes for %s\n",
                                mdname(mddev));
                mddev->sysfs_action = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_action");
+               mddev->sysfs_completed = sysfs_get_dirent_safe(mddev->kobj.sd, "sync_completed");
+               mddev->sysfs_degraded = sysfs_get_dirent_safe(mddev->kobj.sd, "degraded");
        } else if (mddev->ro == 2) /* auto-readonly not meaningful */
                mddev->ro = 0;
 
index a37d7d1..33df083 100644 (file)
@@ -1193,18 +1193,6 @@ config MFD_SKY81452
          This driver can also be built as a module.  If so, the module
          will be called sky81452.
 
-config MFD_SMSC
-       bool "SMSC ECE1099 series chips"
-       depends on I2C=y
-       select MFD_CORE
-       select REGMAP_I2C
-       help
-         If you say yes here you get support for the
-         ece1099 chips from SMSC.
-
-         To compile this driver as a module, choose M here: the
-         module will be called smsc.
-
 config MFD_SC27XX_PMIC
        tristate "Spreadtrum SC27xx PMICs"
        depends on ARCH_SPRD || COMPILE_TEST
@@ -2053,6 +2041,27 @@ config MFD_WCD934X
          This driver provides common support WCD934x audio codec and its
          associated Pin Controller, Soundwire Controller and Audio codec.
 
+config MFD_KHADAS_MCU
+       tristate "Support for Khadas System control Microcontroller"
+       depends on I2C
+       depends on ARCH_MESON || ARCH_ROCKCHIP || COMPILE_TEST
+       select MFD_CORE
+       select REGMAP_I2C
+       help
+         Support for the Khadas System control Microcontroller interface
+         present on their VIM and Edge boards.
+
+         This Microcontroller is present on the Khadas VIM1, VIM2, VIM3 and
+         Edge boards.
+
+         It provides multiple boot control features like password check,
+         power-on options, power-off control and system FAN control on recent
+         boards.
+
+         This driver provides common support for accessing the device,
+         additional drivers must be enabled in order to use the functionality
+         of the device.
+
 menu "Multimedia Capabilities Port drivers"
        depends on ARCH_SA1100
 
index 9367a92..a60e5f8 100644 (file)
@@ -127,7 +127,6 @@ obj-$(CONFIG_MFD_CPCAP)             += motorola-cpcap.o
 obj-$(CONFIG_MCP)              += mcp-core.o
 obj-$(CONFIG_MCP_SA11X0)       += mcp-sa11x0.o
 obj-$(CONFIG_MCP_UCB1200)      += ucb1x00-core.o
-obj-$(CONFIG_MFD_SMSC)        += smsc-ece1099.o
 obj-$(CONFIG_MCP_UCB1200_TS)   += ucb1x00-ts.o
 
 ifeq ($(CONFIG_SA1100_ASSABET),y)
@@ -262,5 +261,6 @@ obj-$(CONFIG_MFD_ROHM_BD70528)      += rohm-bd70528.o
 obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o
 obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
 obj-$(CONFIG_MFD_STMFX)        += stmfx.o
+obj-$(CONFIG_MFD_KHADAS_MCU)   += khadas-mcu.o
 
 obj-$(CONFIG_SGI_MFD_IOC3)     += ioc3.o
index 57723f1..ee71ae0 100644 (file)
@@ -498,7 +498,7 @@ static ssize_t ab3100_get_set_reg(struct file *file,
        int i = 0;
 
        /* Get userspace string and assure termination */
-       buf_size = min(count, (sizeof(buf)-1));
+       buf_size = min((ssize_t)count, (ssize_t)(sizeof(buf)-1));
        if (copy_from_user(buf, user_buf, buf_size))
                return -EFAULT;
        buf[buf_size] = 0;
index c4751fb..c393102 100644 (file)
 
 /**
  * struct ab3100_otp
- * @dev containing device
- * @locked whether the OTP is locked, after locking, no more bits
+ * @dev: containing device
+ * @locked: whether the OTP is locked, after locking, no more bits
  *       can be changed but before locking it is still possible
  *       to change bits from 1->0.
- * @freq clocking frequency for the OTP, this frequency is either
+ * @freq: clocking frequency for the OTP, this frequency is either
  *       32768Hz or 1MHz/30
- * @paf product activation flag, indicates whether this is a real
+ * @paf: product activation flag, indicates whether this is a real
  *       product (paf true) or a lab board etc (paf false)
- * @imeich if this is set it is possible to override the
+ * @imeich: if this is set it is possible to override the
  *       IMEI number found in the tac, fac and svn fields with
  *       (secured) software
- * @cid customer ID
- * @tac type allocation code of the IMEI
- * @fac final assembly code of the IMEI
- * @svn software version number of the IMEI
- * @debugfs a debugfs file used when dumping to file
+ * @cid: customer ID
+ * @tac: type allocation code of the IMEI
+ * @fac: final assembly code of the IMEI
+ * @svn: software version number of the IMEI
+ * @debugfs: a debugfs file used when dumping to file
  */
 struct ab3100_otp {
        struct device *dev;
index 1a9a341..6d1bf7c 100644 (file)
@@ -1801,7 +1801,7 @@ static ssize_t ab8500_hwreg_write(struct file *file,
        int buf_size, ret;
 
        /* Get userspace string and assure termination */
-       buf_size = min(count, (sizeof(buf)-1));
+       buf_size = min((int)count, (int)(sizeof(buf)-1));
        if (copy_from_user(buf, user_buf, buf_size))
                return -EFAULT;
        buf[buf_size] = 0;
index d2a13a5..41076d1 100644 (file)
 /**
  * struct altr_sysmgr - Altera SOCFPGA System Manager
  * @regmap: the regmap used for System Manager accesses.
- * @base  : the base address for the System Manager
  */
 struct altr_sysmgr {
        struct regmap   *regmap;
-       resource_size_t *base;
 };
 
 static struct platform_driver altr_sysmgr_driver;
@@ -91,6 +89,9 @@ static struct regmap_config altr_sysmgr_regmap_cfg = {
  * altr_sysmgr_regmap_lookup_by_phandle
  * Find the sysmgr previous configured in probe() and return regmap property.
  * Return: regmap if found or error if not found.
+ *
+ * @np: Pointer to device's Device Tree node
+ * @property: Device Tree property name which references the sysmgr
  */
 struct regmap *altr_sysmgr_regmap_lookup_by_phandle(struct device_node *np,
                                                    const char *property)
@@ -127,6 +128,7 @@ static int sysmgr_probe(struct platform_device *pdev)
        struct regmap_config sysmgr_config = altr_sysmgr_regmap_cfg;
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
+       void __iomem *base;
 
        sysmgr = devm_kzalloc(dev, sizeof(*sysmgr), GFP_KERNEL);
        if (!sysmgr)
@@ -139,22 +141,19 @@ static int sysmgr_probe(struct platform_device *pdev)
        sysmgr_config.max_register = resource_size(res) -
                                     sysmgr_config.reg_stride;
        if (of_device_is_compatible(np, "altr,sys-mgr-s10")) {
-               /* Need physical address for SMCC call */
-               sysmgr->base = (resource_size_t *)res->start;
                sysmgr_config.reg_read = s10_protected_reg_read;
                sysmgr_config.reg_write = s10_protected_reg_write;
 
-               regmap = devm_regmap_init(dev, NULL, sysmgr->base,
+               /* Need physical address for SMCC call */
+               regmap = devm_regmap_init(dev, NULL, (void *)res->start,
                                          &sysmgr_config);
        } else {
-               sysmgr->base = devm_ioremap(dev, res->start,
-                                           resource_size(res));
-               if (!sysmgr->base)
+               base = devm_ioremap(dev, res->start, resource_size(res));
+               if (!base)
                        return -ENOMEM;
 
                sysmgr_config.max_register = res->end - res->start - 3;
-               regmap = devm_regmap_init_mmio(dev, sysmgr->base,
-                                              &sysmgr_config);
+               regmap = devm_regmap_init_mmio(dev, base, &sysmgr_config);
        }
 
        if (IS_ERR(regmap)) {
index f73cf76..000cb82 100644 (file)
@@ -80,7 +80,7 @@ int arizona_clk32k_disable(struct arizona *arizona)
 {
        mutex_lock(&arizona->clk_lock);
 
-       BUG_ON(arizona->clk32k_ref <= 0);
+       WARN_ON(arizona->clk32k_ref <= 0);
 
        arizona->clk32k_ref--;
 
@@ -1426,6 +1426,15 @@ err_irq:
        arizona_irq_exit(arizona);
 err_pm:
        pm_runtime_disable(arizona->dev);
+
+       switch (arizona->pdata.clk32k_src) {
+       case ARIZONA_32KZ_MCLK1:
+       case ARIZONA_32KZ_MCLK2:
+               arizona_clk32k_disable(arizona);
+               break;
+       default:
+               break;
+       }
 err_reset:
        arizona_enable_reset(arizona);
        regulator_disable(arizona->dcvdd);
@@ -1448,6 +1457,15 @@ int arizona_dev_exit(struct arizona *arizona)
        regulator_disable(arizona->dcvdd);
        regulator_put(arizona->dcvdd);
 
+       switch (arizona->pdata.clk32k_src) {
+       case ARIZONA_32KZ_MCLK1:
+       case ARIZONA_32KZ_MCLK2:
+               arizona_clk32k_disable(arizona);
+               break;
+       default:
+               break;
+       }
+
        mfd_remove_devices(arizona->dev);
        arizona_free_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, arizona);
        arizona_free_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, arizona);
index 1fa2ec9..d96f1d6 100644 (file)
@@ -237,7 +237,7 @@ EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_set_cycle);
  * atmel_smc_cs_conf_apply - apply an SMC CS conf
  * @regmap: the SMC regmap
  * @cs: the CS id
- * @conf the SMC CS conf to apply
+ * @conf: the SMC CS conf to apply
  *
  * Applies an SMC CS configuration.
  * Only valid on at91sam9/avr32 SoCs.
@@ -257,7 +257,7 @@ EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_apply);
  * @regmap: the HSMC regmap
  * @cs: the CS id
  * @layout: the layout of registers
- * @conf the SMC CS conf to apply
+ * @conf: the SMC CS conf to apply
  *
  * Applies an SMC CS configuration.
  * Only valid on post-sama5 SoCs.
index 14f9df7..068e9c0 100644 (file)
@@ -63,6 +63,7 @@ static const struct of_device_id axp20x_i2c_of_match[] = {
        { .compatible = "x-powers,axp209", .data = (void *)AXP209_ID },
        { .compatible = "x-powers,axp221", .data = (void *)AXP221_ID },
        { .compatible = "x-powers,axp223", .data = (void *)AXP223_ID },
+       { .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
        { .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
        { },
 };
@@ -74,11 +75,13 @@ static const struct i2c_device_id axp20x_i2c_id[] = {
        { "axp209", 0 },
        { "axp221", 0 },
        { "axp223", 0 },
+       { "axp803", 0 },
        { "axp806", 0 },
        { },
 };
 MODULE_DEVICE_TABLE(i2c, axp20x_i2c_id);
 
+#ifdef CONFIG_ACPI
 static const struct acpi_device_id axp20x_i2c_acpi_match[] = {
        {
                .id = "INT33F4",
@@ -87,6 +90,7 @@ static const struct acpi_device_id axp20x_i2c_acpi_match[] = {
        { },
 };
 MODULE_DEVICE_TABLE(acpi, axp20x_i2c_acpi_match);
+#endif
 
 static struct i2c_driver axp20x_i2c_driver = {
        .driver = {
index 32c2b91..d07b43d 100644 (file)
@@ -24,7 +24,7 @@ static struct class cros_class = {
 };
 
 /**
- * cros_feature_to_name - CrOS feature id to name/short description.
+ * struct cros_feature_to_name - CrOS feature id to name/short description.
  * @id: The feature identifier.
  * @name: Device name associated with the feature id.
  * @desc: Short name that will be displayed.
@@ -36,7 +36,7 @@ struct cros_feature_to_name {
 };
 
 /**
- * cros_feature_to_cells - CrOS feature id to mfd cells association.
+ * struct cros_feature_to_cells - CrOS feature id to mfd cells association.
  * @id: The feature identifier.
  * @mfd_cells: Pointer to the array of mfd cells that needs to be added.
  * @num_cells: Number of mfd cells into the array.
index b125f90..a353d52 100644 (file)
@@ -160,7 +160,6 @@ static int da9063_clear_fault_log(struct da9063 *da9063)
 
 int da9063_device_init(struct da9063 *da9063, unsigned int irq)
 {
-       int model, variant_id, variant_code;
        int ret;
 
        ret = da9063_clear_fault_log(da9063);
@@ -171,36 +170,6 @@ int da9063_device_init(struct da9063 *da9063, unsigned int irq)
        da9063->irq_base = -1;
        da9063->chip_irq = irq;
 
-       ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_ID, &model);
-       if (ret < 0) {
-               dev_err(da9063->dev, "Cannot read chip model id.\n");
-               return -EIO;
-       }
-       if (model != PMIC_CHIP_ID_DA9063) {
-               dev_err(da9063->dev, "Invalid chip model id: 0x%02x\n", model);
-               return -ENODEV;
-       }
-
-       ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &variant_id);
-       if (ret < 0) {
-               dev_err(da9063->dev, "Cannot read chip variant id.\n");
-               return -EIO;
-       }
-
-       variant_code = variant_id >> DA9063_CHIP_VARIANT_SHIFT;
-
-       dev_info(da9063->dev,
-                "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n",
-                model, variant_id);
-
-       if (variant_code < PMIC_DA9063_BB && variant_code != PMIC_DA9063_AD) {
-               dev_err(da9063->dev,
-                       "Cannot support variant code: 0x%02X\n", variant_code);
-               return -ENODEV;
-       }
-
-       da9063->variant_code = variant_code;
-
        ret = da9063_irq_init(da9063);
        if (ret) {
                dev_err(da9063->dev, "Cannot initialize interrupts.\n");
index 455de74..b8217ad 100644 (file)
 #include <linux/of.h>
 #include <linux/regulator/of_regulator.h>
 
+/*
+ * Raw I2C access required for just accessing chip and variant info before we
+ * know which device is present. The info read from the device using this
+ * approach is then used to select the correct regmap tables.
+ */
+
+#define DA9063_REG_PAGE_SIZE           0x100
+#define DA9063_REG_PAGED_ADDR_MASK     0xFF
+
+enum da9063_page_sel_buf_fmt {
+       DA9063_PAGE_SEL_BUF_PAGE_REG = 0,
+       DA9063_PAGE_SEL_BUF_PAGE_VAL,
+       DA9063_PAGE_SEL_BUF_SIZE,
+};
+
+enum da9063_paged_read_msgs {
+       DA9063_PAGED_READ_MSG_PAGE_SEL = 0,
+       DA9063_PAGED_READ_MSG_REG_SEL,
+       DA9063_PAGED_READ_MSG_DATA,
+       DA9063_PAGED_READ_MSG_CNT,
+};
+
+static int da9063_i2c_blockreg_read(struct i2c_client *client, u16 addr,
+                                   u8 *buf, int count)
+{
+       struct i2c_msg xfer[DA9063_PAGED_READ_MSG_CNT];
+       u8 page_sel_buf[DA9063_PAGE_SEL_BUF_SIZE];
+       u8 page_num, paged_addr;
+       int ret;
+
+       /* Determine page info based on register address */
+       page_num = (addr / DA9063_REG_PAGE_SIZE);
+       if (page_num > 1) {
+               dev_err(&client->dev, "Invalid register address provided\n");
+               return -EINVAL;
+       }
+
+       paged_addr = (addr % DA9063_REG_PAGE_SIZE) & DA9063_REG_PAGED_ADDR_MASK;
+       page_sel_buf[DA9063_PAGE_SEL_BUF_PAGE_REG] = DA9063_REG_PAGE_CON;
+       page_sel_buf[DA9063_PAGE_SEL_BUF_PAGE_VAL] =
+               (page_num << DA9063_I2C_PAGE_SEL_SHIFT) & DA9063_REG_PAGE_MASK;
+
+       /* Write reg address, page selection */
+       xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].addr = client->addr;
+       xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].flags = 0;
+       xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].len = DA9063_PAGE_SEL_BUF_SIZE;
+       xfer[DA9063_PAGED_READ_MSG_PAGE_SEL].buf = page_sel_buf;
+
+       /* Select register address */
+       xfer[DA9063_PAGED_READ_MSG_REG_SEL].addr = client->addr;
+       xfer[DA9063_PAGED_READ_MSG_REG_SEL].flags = 0;
+       xfer[DA9063_PAGED_READ_MSG_REG_SEL].len = sizeof(paged_addr);
+       xfer[DA9063_PAGED_READ_MSG_REG_SEL].buf = &paged_addr;
+
+       /* Read data */
+       xfer[DA9063_PAGED_READ_MSG_DATA].addr = client->addr;
+       xfer[DA9063_PAGED_READ_MSG_DATA].flags = I2C_M_RD;
+       xfer[DA9063_PAGED_READ_MSG_DATA].len = count;
+       xfer[DA9063_PAGED_READ_MSG_DATA].buf = buf;
+
+       ret = i2c_transfer(client->adapter, xfer, DA9063_PAGED_READ_MSG_CNT);
+       if (ret < 0) {
+               dev_err(&client->dev, "Paged block read failed: %d\n", ret);
+               return ret;
+       }
+
+       if (ret != DA9063_PAGED_READ_MSG_CNT) {
+               dev_err(&client->dev, "Paged block read failed to complete\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+enum {
+       DA9063_DEV_ID_REG = 0,
+       DA9063_VAR_ID_REG,
+       DA9063_CHIP_ID_REGS,
+};
+
+static int da9063_get_device_type(struct i2c_client *i2c, struct da9063 *da9063)
+{
+       u8 buf[DA9063_CHIP_ID_REGS];
+       int ret;
+
+       ret = da9063_i2c_blockreg_read(i2c, DA9063_REG_DEVICE_ID, buf,
+                                      DA9063_CHIP_ID_REGS);
+       if (ret)
+               return ret;
+
+       if (buf[DA9063_DEV_ID_REG] != PMIC_CHIP_ID_DA9063) {
+               dev_err(da9063->dev,
+                       "Invalid chip device ID: 0x%02x\n",
+                       buf[DA9063_DEV_ID_REG]);
+               return -ENODEV;
+       }
+
+       dev_info(da9063->dev,
+                "Device detected (chip-ID: 0x%02X, var-ID: 0x%02X)\n",
+                buf[DA9063_DEV_ID_REG], buf[DA9063_VAR_ID_REG]);
+
+       da9063->variant_code =
+               (buf[DA9063_VAR_ID_REG] & DA9063_VARIANT_ID_MRC_MASK)
+               >> DA9063_VARIANT_ID_MRC_SHIFT;
+
+       return 0;
+}
+
+/*
+ * Variant specific regmap configs
+ */
+
 static const struct regmap_range da9063_ad_readable_ranges[] = {
        regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_AD_REG_SECOND_D),
        regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
        regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
        regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_AD_REG_GP_ID_19),
-       regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT),
+       regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID),
 };
 
 static const struct regmap_range da9063_ad_writeable_ranges[] = {
@@ -72,7 +184,7 @@ static const struct regmap_range da9063_bb_readable_ranges[] = {
        regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
        regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
        regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_19),
-       regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT),
+       regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID),
 };
 
 static const struct regmap_range da9063_bb_writeable_ranges[] = {
@@ -85,7 +197,7 @@ static const struct regmap_range da9063_bb_writeable_ranges[] = {
        regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_19),
 };
 
-static const struct regmap_range da9063_bb_volatile_ranges[] = {
+static const struct regmap_range da9063_bb_da_volatile_ranges[] = {
        regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D),
        regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B),
        regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F),
@@ -107,9 +219,9 @@ static const struct regmap_access_table da9063_bb_writeable_table = {
        .n_yes_ranges = ARRAY_SIZE(da9063_bb_writeable_ranges),
 };
 
-static const struct regmap_access_table da9063_bb_volatile_table = {
-       .yes_ranges = da9063_bb_volatile_ranges,
-       .n_yes_ranges = ARRAY_SIZE(da9063_bb_volatile_ranges),
+static const struct regmap_access_table da9063_bb_da_volatile_table = {
+       .yes_ranges = da9063_bb_da_volatile_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063_bb_da_volatile_ranges),
 };
 
 static const struct regmap_range da9063l_bb_readable_ranges[] = {
@@ -117,7 +229,7 @@ static const struct regmap_range da9063l_bb_readable_ranges[] = {
        regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
        regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
        regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_19),
-       regmap_reg_range(DA9063_REG_CHIP_ID, DA9063_REG_CHIP_VARIANT),
+       regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID),
 };
 
 static const struct regmap_range da9063l_bb_writeable_ranges[] = {
@@ -129,7 +241,7 @@ static const struct regmap_range da9063l_bb_writeable_ranges[] = {
        regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_19),
 };
 
-static const struct regmap_range da9063l_bb_volatile_ranges[] = {
+static const struct regmap_range da9063l_bb_da_volatile_ranges[] = {
        regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_EVENT_D),
        regmap_reg_range(DA9063_REG_CONTROL_A, DA9063_REG_CONTROL_B),
        regmap_reg_range(DA9063_REG_CONTROL_E, DA9063_REG_CONTROL_F),
@@ -151,15 +263,70 @@ static const struct regmap_access_table da9063l_bb_writeable_table = {
        .n_yes_ranges = ARRAY_SIZE(da9063l_bb_writeable_ranges),
 };
 
-static const struct regmap_access_table da9063l_bb_volatile_table = {
-       .yes_ranges = da9063l_bb_volatile_ranges,
-       .n_yes_ranges = ARRAY_SIZE(da9063l_bb_volatile_ranges),
+static const struct regmap_access_table da9063l_bb_da_volatile_table = {
+       .yes_ranges = da9063l_bb_da_volatile_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063l_bb_da_volatile_ranges),
+};
+
+static const struct regmap_range da9063_da_readable_ranges[] = {
+       regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_BB_REG_SECOND_D),
+       regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
+       regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
+       regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_11),
+       regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID),
+};
+
+static const struct regmap_range da9063_da_writeable_ranges[] = {
+       regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON),
+       regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON),
+       regmap_reg_range(DA9063_REG_COUNT_S, DA9063_BB_REG_ALARM_Y),
+       regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
+       regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
+       regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_BB_REG_MON_REG_4),
+       regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_11),
+};
+
+static const struct regmap_access_table da9063_da_readable_table = {
+       .yes_ranges = da9063_da_readable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063_da_readable_ranges),
+};
+
+static const struct regmap_access_table da9063_da_writeable_table = {
+       .yes_ranges = da9063_da_writeable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063_da_writeable_ranges),
+};
+
+static const struct regmap_range da9063l_da_readable_ranges[] = {
+       regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_MON_A10_RES),
+       regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
+       regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
+       regmap_reg_range(DA9063_REG_T_OFFSET, DA9063_BB_REG_GP_ID_11),
+       regmap_reg_range(DA9063_REG_DEVICE_ID, DA9063_REG_VARIANT_ID),
+};
+
+static const struct regmap_range da9063l_da_writeable_ranges[] = {
+       regmap_reg_range(DA9063_REG_PAGE_CON, DA9063_REG_PAGE_CON),
+       regmap_reg_range(DA9063_REG_FAULT_LOG, DA9063_REG_VSYS_MON),
+       regmap_reg_range(DA9063_REG_SEQ, DA9063_REG_ID_32_31),
+       regmap_reg_range(DA9063_REG_SEQ_A, DA9063_REG_AUTO3_LOW),
+       regmap_reg_range(DA9063_REG_CONFIG_I, DA9063_BB_REG_MON_REG_4),
+       regmap_reg_range(DA9063_BB_REG_GP_ID_0, DA9063_BB_REG_GP_ID_11),
+};
+
+static const struct regmap_access_table da9063l_da_readable_table = {
+       .yes_ranges = da9063l_da_readable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063l_da_readable_ranges),
+};
+
+static const struct regmap_access_table da9063l_da_writeable_table = {
+       .yes_ranges = da9063l_da_writeable_ranges,
+       .n_yes_ranges = ARRAY_SIZE(da9063l_da_writeable_ranges),
 };
 
 static const struct regmap_range_cfg da9063_range_cfg[] = {
        {
                .range_min = DA9063_REG_PAGE_CON,
-               .range_max = DA9063_REG_CHIP_VARIANT,
+               .range_max = DA9063_REG_CONFIG_ID,
                .selector_reg = DA9063_REG_PAGE_CON,
                .selector_mask = 1 << DA9063_I2C_PAGE_SEL_SHIFT,
                .selector_shift = DA9063_I2C_PAGE_SEL_SHIFT,
@@ -173,7 +340,7 @@ static struct regmap_config da9063_regmap_config = {
        .val_bits = 8,
        .ranges = da9063_range_cfg,
        .num_ranges = ARRAY_SIZE(da9063_range_cfg),
-       .max_register = DA9063_REG_CHIP_VARIANT,
+       .max_register = DA9063_REG_CONFIG_ID,
 
        .cache_type = REGCACHE_RBTREE,
 };
@@ -199,18 +366,72 @@ static int da9063_i2c_probe(struct i2c_client *i2c,
        da9063->chip_irq = i2c->irq;
        da9063->type = id->driver_data;
 
-       if (da9063->variant_code == PMIC_DA9063_AD) {
-               da9063_regmap_config.rd_table = &da9063_ad_readable_table;
-               da9063_regmap_config.wr_table = &da9063_ad_writeable_table;
-               da9063_regmap_config.volatile_table = &da9063_ad_volatile_table;
-       } else if (da9063->type == PMIC_TYPE_DA9063L) {
-               da9063_regmap_config.rd_table = &da9063l_bb_readable_table;
-               da9063_regmap_config.wr_table = &da9063l_bb_writeable_table;
-               da9063_regmap_config.volatile_table = &da9063l_bb_volatile_table;
-       } else {
-               da9063_regmap_config.rd_table = &da9063_bb_readable_table;
-               da9063_regmap_config.wr_table = &da9063_bb_writeable_table;
-               da9063_regmap_config.volatile_table = &da9063_bb_volatile_table;
+       ret = da9063_get_device_type(i2c, da9063);
+       if (ret)
+               return ret;
+
+       switch (da9063->type) {
+       case PMIC_TYPE_DA9063:
+               switch (da9063->variant_code) {
+               case PMIC_DA9063_AD:
+                       da9063_regmap_config.rd_table =
+                               &da9063_ad_readable_table;
+                       da9063_regmap_config.wr_table =
+                               &da9063_ad_writeable_table;
+                       da9063_regmap_config.volatile_table =
+                               &da9063_ad_volatile_table;
+                       break;
+               case PMIC_DA9063_BB:
+               case PMIC_DA9063_CA:
+                       da9063_regmap_config.rd_table =
+                               &da9063_bb_readable_table;
+                       da9063_regmap_config.wr_table =
+                               &da9063_bb_writeable_table;
+                       da9063_regmap_config.volatile_table =
+                               &da9063_bb_da_volatile_table;
+                       break;
+               case PMIC_DA9063_DA:
+                       da9063_regmap_config.rd_table =
+                               &da9063_da_readable_table;
+                       da9063_regmap_config.wr_table =
+                               &da9063_da_writeable_table;
+                       da9063_regmap_config.volatile_table =
+                               &da9063_bb_da_volatile_table;
+                       break;
+               default:
+                       dev_err(da9063->dev,
+                               "Chip variant not supported for DA9063\n");
+                       return -ENODEV;
+               }
+               break;
+       case PMIC_TYPE_DA9063L:
+               switch (da9063->variant_code) {
+               case PMIC_DA9063_BB:
+               case PMIC_DA9063_CA:
+                       da9063_regmap_config.rd_table =
+                               &da9063l_bb_readable_table;
+                       da9063_regmap_config.wr_table =
+                               &da9063l_bb_writeable_table;
+                       da9063_regmap_config.volatile_table =
+                               &da9063l_bb_da_volatile_table;
+                       break;
+               case PMIC_DA9063_DA:
+                       da9063_regmap_config.rd_table =
+                               &da9063l_da_readable_table;
+                       da9063_regmap_config.wr_table =
+                               &da9063l_da_writeable_table;
+                       da9063_regmap_config.volatile_table =
+                               &da9063l_bb_da_volatile_table;
+                       break;
+               default:
+                       dev_err(da9063->dev,
+                               "Chip variant not supported for DA9063L\n");
+                       return -ENODEV;
+               }
+               break;
+       default:
+               dev_err(da9063->dev, "Chip type not supported\n");
+               return -ENODEV;
        }
 
        da9063->regmap = devm_regmap_init_i2c(i2c, &da9063_regmap_config);
index 0452b43..a9d9c1c 100644 (file)
@@ -2276,6 +2276,8 @@ bool db8500_prcmu_is_ac_wake_requested(void)
  *
  * Saves the reset reason code and then sets the APE_SOFTRST register which
  * fires interrupt to fw
+ *
+ * @reset_code: The reason for system reset
  */
 void db8500_prcmu_system_reset(u16 reset_code)
 {
@@ -3004,10 +3006,6 @@ static int db8500_prcmu_register_ab8500(struct device *parent)
        return mfd_add_devices(parent, 0, ab850x_cell, 1, NULL, 0, NULL);
 }
 
-/**
- * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
- *
- */
 static int db8500_prcmu_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
index 39276fa..83e676a 100644 (file)
@@ -287,7 +287,11 @@ static void dln2_rx(struct urb *urb)
        len = urb->actual_length - sizeof(struct dln2_header);
 
        if (handle == DLN2_HANDLE_EVENT) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&dln2->event_cb_lock, flags);
                dln2_run_event_callbacks(dln2, id, echo, data, len);
+               spin_unlock_irqrestore(&dln2->event_cb_lock, flags);
        } else {
                /* URB will be re-submitted in _dln2_transfer (free_rx_slot) */
                if (dln2_transfer_complete(dln2, urb, handle, echo))
index edfc172..eba88b8 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
  *              http://www.hisilicon.com
  * Copyright (c) <2013-2017> Linaro Ltd.
- *              http://www.linaro.org
+ *              https://www.linaro.org
  *
  * Author: Guodong Xu <guodong.xu@linaro.org>
  */
index 0462226..9a58032 100644 (file)
@@ -201,6 +201,9 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
        { PCI_VDEVICE(INTEL, 0x1ac4), (kernel_ulong_t)&bxt_info },
        { PCI_VDEVICE(INTEL, 0x1ac6), (kernel_ulong_t)&bxt_info },
        { PCI_VDEVICE(INTEL, 0x1aee), (kernel_ulong_t)&bxt_uart_info },
+       /* EBG */
+       { PCI_VDEVICE(INTEL, 0x1bad), (kernel_ulong_t)&bxt_uart_info },
+       { PCI_VDEVICE(INTEL, 0x1bae), (kernel_ulong_t)&bxt_uart_info },
        /* GLK */
        { PCI_VDEVICE(INTEL, 0x31ac), (kernel_ulong_t)&glk_i2c_info },
        { PCI_VDEVICE(INTEL, 0x31ae), (kernel_ulong_t)&glk_i2c_info },
@@ -230,6 +233,22 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
        { PCI_VDEVICE(INTEL, 0x34ea), (kernel_ulong_t)&bxt_i2c_info },
        { PCI_VDEVICE(INTEL, 0x34eb), (kernel_ulong_t)&bxt_i2c_info },
        { PCI_VDEVICE(INTEL, 0x34fb), (kernel_ulong_t)&spt_info },
+       /* TGL-H */
+       { PCI_VDEVICE(INTEL, 0x43a7), (kernel_ulong_t)&bxt_uart_info },
+       { PCI_VDEVICE(INTEL, 0x43a8), (kernel_ulong_t)&bxt_uart_info },
+       { PCI_VDEVICE(INTEL, 0x43a9), (kernel_ulong_t)&bxt_uart_info },
+       { PCI_VDEVICE(INTEL, 0x43aa), (kernel_ulong_t)&bxt_info },
+       { PCI_VDEVICE(INTEL, 0x43ab), (kernel_ulong_t)&bxt_info },
+       { PCI_VDEVICE(INTEL, 0x43ad), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x43ae), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x43d8), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x43da), (kernel_ulong_t)&bxt_uart_info },
+       { PCI_VDEVICE(INTEL, 0x43e8), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x43e9), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x43ea), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x43eb), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x43fb), (kernel_ulong_t)&bxt_info },
+       { PCI_VDEVICE(INTEL, 0x43fd), (kernel_ulong_t)&bxt_info },
        /* EHL */
        { PCI_VDEVICE(INTEL, 0x4b28), (kernel_ulong_t)&bxt_uart_info },
        { PCI_VDEVICE(INTEL, 0x4b29), (kernel_ulong_t)&bxt_uart_info },
index bd94c98..71da861 100644 (file)
@@ -91,13 +91,8 @@ static int bcove_ipc_byte_reg_write(void *context, unsigned int reg,
 {
        struct intel_soc_pmic *pmic = context;
        u8 ipc_in = val;
-       int ret;
 
-       ret = intel_scu_ipc_dev_iowrite8(pmic->scu, reg, ipc_in);
-       if (ret)
-               return ret;
-
-       return 0;
+       return intel_scu_ipc_dev_iowrite8(pmic->scu, reg, ipc_in);
 }
 
 static const struct regmap_config bcove_regmap_config = {
index f48e21d..52bec01 100644 (file)
@@ -79,39 +79,31 @@ enum kempld_cells {
        KEMPLD_UART,
 };
 
-static const struct mfd_cell kempld_devs[] = {
-       [KEMPLD_I2C] = {
-               .name = "kempld-i2c",
-       },
-       [KEMPLD_WDT] = {
-               .name = "kempld-wdt",
-       },
-       [KEMPLD_GPIO] = {
-               .name = "kempld-gpio",
-       },
-       [KEMPLD_UART] = {
-               .name = "kempld-uart",
-       },
+static const char *kempld_dev_names[] = {
+       [KEMPLD_I2C] = "kempld-i2c",
+       [KEMPLD_WDT] = "kempld-wdt",
+       [KEMPLD_GPIO] = "kempld-gpio",
+       [KEMPLD_UART] = "kempld-uart",
 };
 
-#define KEMPLD_MAX_DEVS        ARRAY_SIZE(kempld_devs)
+#define KEMPLD_MAX_DEVS        ARRAY_SIZE(kempld_dev_names)
 
 static int kempld_register_cells_generic(struct kempld_device_data *pld)
 {
-       struct mfd_cell devs[KEMPLD_MAX_DEVS];
+       struct mfd_cell devs[KEMPLD_MAX_DEVS] = {};
        int i = 0;
 
        if (pld->feature_mask & KEMPLD_FEATURE_BIT_I2C)
-               devs[i++] = kempld_devs[KEMPLD_I2C];
+               devs[i++].name = kempld_dev_names[KEMPLD_I2C];
 
        if (pld->feature_mask & KEMPLD_FEATURE_BIT_WATCHDOG)
-               devs[i++] = kempld_devs[KEMPLD_WDT];
+               devs[i++].name = kempld_dev_names[KEMPLD_WDT];
 
        if (pld->feature_mask & KEMPLD_FEATURE_BIT_GPIO)
-               devs[i++] = kempld_devs[KEMPLD_GPIO];
+               devs[i++].name = kempld_dev_names[KEMPLD_GPIO];
 
        if (pld->feature_mask & KEMPLD_FEATURE_MASK_UART)
-               devs[i++] = kempld_devs[KEMPLD_UART];
+               devs[i++].name = kempld_dev_names[KEMPLD_UART];
 
        return mfd_add_devices(pld->dev, -1, devs, i, NULL, 0, NULL);
 }
diff --git a/drivers/mfd/khadas-mcu.c b/drivers/mfd/khadas-mcu.c
new file mode 100644 (file)
index 0000000..44d5bb4
--- /dev/null
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Driver for Khadas System control Microcontroller
+ *
+ * Copyright (C) 2020 BayLibre SAS
+ *
+ * Author(s): Neil Armstrong <narmstrong@baylibre.com>
+ */
+#include <linux/bitfield.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/khadas-mcu.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+
+static bool khadas_mcu_reg_volatile(struct device *dev, unsigned int reg)
+{
+       if (reg >= KHADAS_MCU_USER_DATA_0_REG &&
+           reg < KHADAS_MCU_PWR_OFF_CMD_REG)
+               return true;
+
+       switch (reg) {
+       case KHADAS_MCU_PWR_OFF_CMD_REG:
+       case KHADAS_MCU_PASSWD_START_REG:
+       case KHADAS_MCU_CHECK_VEN_PASSWD_REG:
+       case KHADAS_MCU_CHECK_USER_PASSWD_REG:
+       case KHADAS_MCU_WOL_INIT_START_REG:
+       case KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static bool khadas_mcu_reg_writeable(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case KHADAS_MCU_PASSWD_VEN_0_REG:
+       case KHADAS_MCU_PASSWD_VEN_1_REG:
+       case KHADAS_MCU_PASSWD_VEN_2_REG:
+       case KHADAS_MCU_PASSWD_VEN_3_REG:
+       case KHADAS_MCU_PASSWD_VEN_4_REG:
+       case KHADAS_MCU_PASSWD_VEN_5_REG:
+       case KHADAS_MCU_MAC_0_REG:
+       case KHADAS_MCU_MAC_1_REG:
+       case KHADAS_MCU_MAC_2_REG:
+       case KHADAS_MCU_MAC_3_REG:
+       case KHADAS_MCU_MAC_4_REG:
+       case KHADAS_MCU_MAC_5_REG:
+       case KHADAS_MCU_USID_0_REG:
+       case KHADAS_MCU_USID_1_REG:
+       case KHADAS_MCU_USID_2_REG:
+       case KHADAS_MCU_USID_3_REG:
+       case KHADAS_MCU_USID_4_REG:
+       case KHADAS_MCU_USID_5_REG:
+       case KHADAS_MCU_VERSION_0_REG:
+       case KHADAS_MCU_VERSION_1_REG:
+       case KHADAS_MCU_DEVICE_NO_0_REG:
+       case KHADAS_MCU_DEVICE_NO_1_REG:
+       case KHADAS_MCU_FACTORY_TEST_REG:
+       case KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG:
+               return false;
+       default:
+               return true;
+       }
+}
+
+static const struct regmap_config khadas_mcu_regmap_config = {
+       .reg_bits       = 8,
+       .reg_stride     = 1,
+       .val_bits       = 8,
+       .max_register   = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
+       .volatile_reg   = khadas_mcu_reg_volatile,
+       .writeable_reg  = khadas_mcu_reg_writeable,
+       .cache_type     = REGCACHE_RBTREE,
+};
+
+static struct mfd_cell khadas_mcu_fan_cells[] = {
+       /* VIM1/2 Rev13+ and VIM3 only */
+       { .name = "khadas-mcu-fan-ctrl", },
+};
+
+static struct mfd_cell khadas_mcu_cells[] = {
+       { .name = "khadas-mcu-user-mem", },
+};
+
+static int khadas_mcu_probe(struct i2c_client *client,
+                      const struct i2c_device_id *id)
+{
+       struct device *dev = &client->dev;
+       struct khadas_mcu *ddata;
+       int ret;
+
+       ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+       if (!ddata)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, ddata);
+
+       ddata->dev = dev;
+
+       ddata->regmap = devm_regmap_init_i2c(client, &khadas_mcu_regmap_config);
+       if (IS_ERR(ddata->regmap)) {
+               ret = PTR_ERR(ddata->regmap);
+               dev_err(dev, "Failed to allocate register map: %d\n", ret);
+               return ret;
+       }
+
+       ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
+                                  khadas_mcu_cells,
+                                  ARRAY_SIZE(khadas_mcu_cells),
+                                  NULL, 0, NULL);
+       if (ret)
+               return ret;
+
+       if (of_find_property(dev->of_node, "#cooling-cells", NULL))
+               return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
+                                           khadas_mcu_fan_cells,
+                                           ARRAY_SIZE(khadas_mcu_fan_cells),
+                                           NULL, 0, NULL);
+
+       return 0;
+}
+
+static const struct of_device_id khadas_mcu_of_match[] = {
+       { .compatible = "khadas,mcu", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, khadas_mcu_of_match);
+
+static struct i2c_driver khadas_mcu_driver = {
+       .driver = {
+               .name = "khadas-mcu-core",
+               .of_match_table = of_match_ptr(khadas_mcu_of_match),
+       },
+       .probe = khadas_mcu_probe,
+};
+module_i2c_driver(khadas_mcu_driver);
+
+MODULE_DESCRIPTION("Khadas MCU core driver");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL v2");
index 34fba06..2537dfa 100644 (file)
@@ -17,7 +17,6 @@
 #define LM3533_MAX_CURRENT_MAX         29800
 #define LM3533_MAX_CURRENT_STEP                800
 
-#define LM3533_BRIGHTNESS_MAX          255
 #define LM3533_PWM_MAX                 0x3f
 
 #define LM3533_REG_PWM_BASE            0x14
@@ -89,41 +88,33 @@ int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax)
 }
 EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current);
 
-#define lm3533_ctrlbank_set(_name, _NAME)                              \
-int lm3533_ctrlbank_set_##_name(struct lm3533_ctrlbank *cb, u8 val)    \
-{                                                                      \
-       u8 reg;                                                         \
-       int ret;                                                        \
-                                                                       \
-       if (val > LM3533_##_NAME##_MAX)                                 \
-               return -EINVAL;                                         \
-                                                                       \
-       reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE);   \
-       ret = lm3533_write(cb->lm3533, reg, val);                       \
-       if (ret)                                                        \
-               dev_err(cb->dev, "failed to set " #_name "\n");         \
-                                                                       \
-       return ret;                                                     \
-}                                                                      \
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_##_name);
-
-#define lm3533_ctrlbank_get(_name, _NAME)                              \
-int lm3533_ctrlbank_get_##_name(struct lm3533_ctrlbank *cb, u8 *val)   \
-{                                                                      \
-       u8 reg;                                                         \
-       int ret;                                                        \
-                                                                       \
-       reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE);   \
-       ret = lm3533_read(cb->lm3533, reg, val);                        \
-       if (ret)                                                        \
-               dev_err(cb->dev, "failed to get " #_name "\n");         \
-                                                                       \
-       return ret;                                                     \
-}                                                                      \
-EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_##_name);
-
-lm3533_ctrlbank_set(brightness, BRIGHTNESS);
-lm3533_ctrlbank_get(brightness, BRIGHTNESS);
+int lm3533_ctrlbank_set_brightness(struct lm3533_ctrlbank *cb, u8 val)
+{
+       u8 reg;
+       int ret;
+
+       reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE);
+       ret = lm3533_write(cb->lm3533, reg, val);
+       if (ret)
+               dev_err(cb->dev, "failed to set brightness\n");
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_brightness);
+
+int lm3533_ctrlbank_get_brightness(struct lm3533_ctrlbank *cb, u8 *val)
+{
+       u8 reg;
+       int ret;
+
+       reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_BRIGHTNESS_BASE);
+       ret = lm3533_read(cb->lm3533, reg, val);
+       if (ret)
+               dev_err(cb->dev, "failed to get brightness\n");
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_brightness);
 
 /*
  * PWM-input control mask:
@@ -135,9 +126,36 @@ lm3533_ctrlbank_get(brightness, BRIGHTNESS);
  *   bit 1 - PWM-input enabled in Zone 0
  *   bit 0 - PWM-input enabled
  */
-lm3533_ctrlbank_set(pwm, PWM);
-lm3533_ctrlbank_get(pwm, PWM);
+int lm3533_ctrlbank_set_pwm(struct lm3533_ctrlbank *cb, u8 val)
+{
+       u8 reg;
+       int ret;
+
+       if (val > LM3533_PWM_MAX)
+               return -EINVAL;
+
+       reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE);
+       ret = lm3533_write(cb->lm3533, reg, val);
+       if (ret)
+               dev_err(cb->dev, "failed to set PWM mask\n");
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_pwm);
+
+int lm3533_ctrlbank_get_pwm(struct lm3533_ctrlbank *cb, u8 *val)
+{
+       u8 reg;
+       int ret;
 
+       reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_PWM_BASE);
+       ret = lm3533_read(cb->lm3533, reg, val);
+       if (ret)
+               dev_err(cb->dev, "failed to get PWM mask\n");
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_pwm);
 
 MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
 MODULE_DESCRIPTION("LM3533 Control Bank interface");
index 873c608..858c9e0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
  *
  * Author: Keerthy <j-keerthy@ti.com>
  *
index 4a5c8ad..2268be9 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
  *
  * Author: Keerthy <j-keerthy@ti.com>
  */
index 7e0835c..8a8d733 100644 (file)
@@ -44,7 +44,10 @@ static const char * const madera_core_supplies[] = {
 };
 
 static const struct mfd_cell madera_ldo1_devs[] = {
-       { .name = "madera-ldo1" },
+       {
+               .name = "madera-ldo1",
+               .level = MFD_DEP_LEVEL_HIGH,
+       },
 };
 
 static const char * const cs47l15_supplies[] = {
@@ -55,8 +58,8 @@ static const char * const cs47l15_supplies[] = {
 
 static const struct mfd_cell cs47l15_devs[] = {
        { .name = "madera-pinctrl", },
-       { .name = "madera-irq" },
-       { .name = "madera-gpio" },
+       { .name = "madera-irq", },
+       { .name = "madera-gpio", },
        {
                .name = "madera-extcon",
                .parent_supplies = cs47l15_supplies,
@@ -108,7 +111,7 @@ static const char * const cs47l85_supplies[] = {
 static const struct mfd_cell cs47l85_devs[] = {
        { .name = "madera-pinctrl", },
        { .name = "madera-irq", },
-       { .name = "madera-micsupp" },
+       { .name = "madera-micsupp", },
        { .name = "madera-gpio", },
        {
                .name = "madera-extcon",
@@ -155,10 +158,10 @@ static const char * const cs47l92_supplies[] = {
 };
 
 static const struct mfd_cell cs47l92_devs[] = {
-       { .name = "madera-pinctrl" },
+       { .name = "madera-pinctrl", },
        { .name = "madera-irq", },
        { .name = "madera-micsupp", },
-       { .name = "madera-gpio" },
+       { .name = "madera-gpio", },
        {
                .name = "madera-extcon",
                .parent_supplies = cs47l92_supplies,
@@ -743,18 +746,22 @@ int madera_dev_exit(struct madera *madera)
        /* Prevent any IRQs being serviced while we clean up */
        disable_irq(madera->irq);
 
-       /*
-        * DCVDD could be supplied by a child node, we must disable it before
-        * removing the children, and prevent PM runtime from turning it back on
-        */
-       pm_runtime_disable(madera->dev);
+       pm_runtime_get_sync(madera->dev);
 
-       clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
+       mfd_remove_devices(madera->dev);
+
+       pm_runtime_disable(madera->dev);
 
        regulator_disable(madera->dcvdd);
        regulator_put(madera->dcvdd);
 
-       mfd_remove_devices(madera->dev);
+       mfd_remove_devices_late(madera->dev);
+
+       pm_runtime_set_suspended(madera->dev);
+       pm_runtime_put_noidle(madera->dev);
+
+       clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
+
        madera_enable_hard_reset(madera);
 
        regulator_bulk_disable(madera->num_core_supplies,
index 6b965eb..7df5b9b 100644 (file)
@@ -88,7 +88,6 @@ static int madera_i2c_probe(struct i2c_client *i2c,
        if (!madera)
                return -ENOMEM;
 
-
        madera->regmap = devm_regmap_init_i2c(i2c, regmap_16bit_config);
        if (IS_ERR(madera->regmap)) {
                ret = PTR_ERR(madera->regmap);
index fd8864c..be185e9 100644 (file)
@@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(maxim_charger_currents);
 int maxim_charger_calc_reg_current(const struct maxim_charger_current *limits,
                unsigned int min_ua, unsigned int max_ua, u8 *dst)
 {
-       unsigned int current_bits = 0xf;
+       unsigned int current_bits;
 
        if (min_ua > max_ua)
                return -EINVAL;
index f5a73af..c3651f0 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/acpi.h>
+#include <linux/list.h>
 #include <linux/property.h>
 #include <linux/mfd/core.h>
 #include <linux/pm_runtime.h>
 #include <linux/module.h>
 #include <linux/irqdomain.h>
 #include <linux/of.h>
+#include <linux/of_address.h>
 #include <linux/regulator/consumer.h>
 
+static LIST_HEAD(mfd_of_node_list);
+
+struct mfd_of_node_entry {
+       struct list_head list;
+       struct device *dev;
+       struct device_node *np;
+};
+
 static struct device_type mfd_dev_type = {
        .name   = "mfd_device",
 };
@@ -107,6 +117,55 @@ static inline void mfd_acpi_add_device(const struct mfd_cell *cell,
 }
 #endif
 
+static int mfd_match_of_node_to_dev(struct platform_device *pdev,
+                                   struct device_node *np,
+                                   const struct mfd_cell *cell)
+{
+#if IS_ENABLED(CONFIG_OF)
+       struct mfd_of_node_entry *of_entry;
+       const __be32 *reg;
+       u64 of_node_addr;
+
+       /* Skip devices 'disabled' by Device Tree */
+       if (!of_device_is_available(np))
+               return -ENODEV;
+
+       /* Skip if OF node has previously been allocated to a device */
+       list_for_each_entry(of_entry, &mfd_of_node_list, list)
+               if (of_entry->np == np)
+                       return -EAGAIN;
+
+       if (!cell->use_of_reg)
+               /* No of_reg defined - allocate first free compatible match */
+               goto allocate_of_node;
+
+       /* We only care about each node's first defined address */
+       reg = of_get_address(np, 0, NULL, NULL);
+       if (!reg)
+               /* OF node does not contatin a 'reg' property to match to */
+               return -EAGAIN;
+
+       of_node_addr = of_read_number(reg, of_n_addr_cells(np));
+
+       if (cell->of_reg != of_node_addr)
+               /* No match */
+               return -EAGAIN;
+
+allocate_of_node:
+       of_entry = kzalloc(sizeof(*of_entry), GFP_KERNEL);
+       if (!of_entry)
+               return -ENOMEM;
+
+       of_entry->dev = &pdev->dev;
+       of_entry->np = np;
+       list_add_tail(&of_entry->list, &mfd_of_node_list);
+
+       pdev->dev.of_node = np;
+       pdev->dev.fwnode = &np->fwnode;
+#endif
+       return 0;
+}
+
 static int mfd_add_device(struct device *parent, int id,
                          const struct mfd_cell *cell,
                          struct resource *mem_base,
@@ -115,6 +174,7 @@ static int mfd_add_device(struct device *parent, int id,
        struct resource *res;
        struct platform_device *pdev;
        struct device_node *np = NULL;
+       struct mfd_of_node_entry *of_entry, *tmp;
        int ret = -ENOMEM;
        int platform_id;
        int r;
@@ -149,19 +209,22 @@ static int mfd_add_device(struct device *parent, int id,
        if (ret < 0)
                goto fail_res;
 
-       if (parent->of_node && cell->of_compatible) {
+       if (IS_ENABLED(CONFIG_OF) && parent->of_node && cell->of_compatible) {
                for_each_child_of_node(parent->of_node, np) {
                        if (of_device_is_compatible(np, cell->of_compatible)) {
-                               if (!of_device_is_available(np)) {
-                                       /* Ignore disabled devices error free */
-                                       ret = 0;
+                               ret = mfd_match_of_node_to_dev(pdev, np, cell);
+                               if (ret == -EAGAIN)
+                                       continue;
+                               if (ret)
                                        goto fail_alias;
-                               }
-                               pdev->dev.of_node = np;
-                               pdev->dev.fwnode = &np->fwnode;
+
                                break;
                        }
                }
+
+               if (!pdev->dev.of_node)
+                       pr_warn("%s: Failed to locate of_node [id: %d]\n",
+                               cell->name, platform_id);
        }
 
        mfd_acpi_add_device(cell, pdev);
@@ -170,13 +233,13 @@ static int mfd_add_device(struct device *parent, int id,
                ret = platform_device_add_data(pdev,
                                        cell->platform_data, cell->pdata_size);
                if (ret)
-                       goto fail_alias;
+                       goto fail_of_entry;
        }
 
        if (cell->properties) {
                ret = platform_device_add_properties(pdev, cell->properties);
                if (ret)
-                       goto fail_alias;
+                       goto fail_of_entry;
        }
 
        for (r = 0; r < cell->num_resources; r++) {
@@ -213,18 +276,18 @@ static int mfd_add_device(struct device *parent, int id,
                        if (has_acpi_companion(&pdev->dev)) {
                                ret = acpi_check_resource_conflict(&res[r]);
                                if (ret)
-                                       goto fail_alias;
+                                       goto fail_of_entry;
                        }
                }
        }
 
        ret = platform_device_add_resources(pdev, res, cell->num_resources);
        if (ret)
-               goto fail_alias;
+               goto fail_of_entry;
 
        ret = platform_device_add(pdev);
        if (ret)
-               goto fail_alias;
+               goto fail_of_entry;
 
        if (cell->pm_runtime_no_callbacks)
                pm_runtime_no_callbacks(&pdev->dev);
@@ -233,6 +296,12 @@ static int mfd_add_device(struct device *parent, int id,
 
        return 0;
 
+fail_of_entry:
+       list_for_each_entry_safe(of_entry, tmp, &mfd_of_node_list, list)
+               if (of_entry->dev == &pdev->dev) {
+                       list_del(&of_entry->list);
+                       kfree(of_entry);
+               }
 fail_alias:
        regulator_bulk_unregister_supply_alias(&pdev->dev,
                                               cell->parent_supplies,
@@ -287,6 +356,7 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
 {
        struct platform_device *pdev;
        const struct mfd_cell *cell;
+       int *level = data;
 
        if (dev->type != &mfd_dev_type)
                return 0;
@@ -294,16 +364,31 @@ static int mfd_remove_devices_fn(struct device *dev, void *data)
        pdev = to_platform_device(dev);
        cell = mfd_get_cell(pdev);
 
+       if (level && cell->level > *level)
+               return 0;
+
        regulator_bulk_unregister_supply_alias(dev, cell->parent_supplies,
                                               cell->num_parent_supplies);
 
+       kfree(cell);
+
        platform_device_unregister(pdev);
        return 0;
 }
 
+void mfd_remove_devices_late(struct device *parent)
+{
+       int level = MFD_DEP_LEVEL_HIGH;
+
+       device_for_each_child_reverse(parent, &level, mfd_remove_devices_fn);
+}
+EXPORT_SYMBOL(mfd_remove_devices_late);
+
 void mfd_remove_devices(struct device *parent)
 {
-       device_for_each_child_reverse(parent, NULL, mfd_remove_devices_fn);
+       int level = MFD_DEP_LEVEL_NORMAL;
+
+       device_for_each_child_reverse(parent, &level, mfd_remove_devices_fn);
 }
 EXPORT_SYMBOL(mfd_remove_devices);
 
@@ -318,6 +403,16 @@ static void devm_mfd_dev_release(struct device *dev, void *res)
  * Returns 0 on success or an appropriate negative error number on failure.
  * All child-devices of the MFD will automatically be removed when it gets
  * unbinded.
+ *
+ * @dev:       Pointer to parent device.
+ * @id:                Can be PLATFORM_DEVID_AUTO to let the Platform API take care
+ *             of device numbering, or will be added to a device's cell_id.
+ * @cells:     Array of (struct mfd_cell)s describing child devices.
+ * @n_devs:    Number of child devices to register.
+ * @mem_base:  Parent register range resource for child devices.
+ * @irq_base:  Base of the range of virtual interrupt numbers allocated for
+ *             this MFD device. Unused if @domain is specified.
+ * @domain:    Interrupt domain to create mappings for hardware interrupts.
  */
 int devm_mfd_add_devices(struct device *dev, int id,
                         const struct mfd_cell *cells, int n_devs,
index 52f38e5..2283d88 100644 (file)
@@ -214,6 +214,28 @@ static const struct regmap_config cpcap_regmap_config = {
        .val_format_endian = REGMAP_ENDIAN_LITTLE,
 };
 
+#ifdef CONFIG_PM_SLEEP
+static int cpcap_suspend(struct device *dev)
+{
+       struct spi_device *spi = to_spi_device(dev);
+
+       disable_irq(spi->irq);
+
+       return 0;
+}
+
+static int cpcap_resume(struct device *dev)
+{
+       struct spi_device *spi = to_spi_device(dev);
+
+       enable_irq(spi->irq);
+
+       return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(cpcap_pm, cpcap_suspend, cpcap_resume);
+
 static const struct mfd_cell cpcap_mfd_devices[] = {
        {
                .name          = "cpcap_adc",
@@ -313,6 +335,7 @@ static struct spi_driver cpcap_driver = {
        .driver = {
                .name = "cpcap-core",
                .of_match_table = cpcap_of_match,
+               .pm = &cpcap_pm,
        },
        .probe = cpcap_probe,
 };
index 1f4f01b..1e6431c 100644 (file)
@@ -2,7 +2,7 @@
 /**
  * omap-usb-host.c - The USBHS core driver for OMAP EHCI & OHCI
  *
- * Copyright (C) 2011-2013 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (C) 2011-2013 Texas Instruments Incorporated - https://www.ti.com
  * Author: Keshava Munegowda <keshava_mgowda@ti.com>
  * Author: Roger Quadros <rogerq@ti.com>
  */
@@ -120,7 +120,7 @@ static inline u32 usbhs_read(void __iomem *base, u32 reg)
 
 /*-------------------------------------------------------------------------*/
 
-/**
+/*
  * Map 'enum usbhs_omap_port_mode' found in <linux/platform_data/usb-omap.h>
  * to the device tree binding portN-mode found in
  * 'Documentation/devicetree/bindings/mfd/omap-usb-host.txt'
@@ -526,6 +526,8 @@ static const struct of_device_id usbhs_child_match_table[] = {
  * usbhs_omap_probe - initialize TI-based HCDs
  *
  * Allocates basic resources for this USB host controller.
+ *
+ * @pdev: Pointer to this device's platform device structure
  */
 static int usbhs_omap_probe(struct platform_device *pdev)
 {
index 4b7f73c..16fad79 100644 (file)
@@ -2,7 +2,7 @@
 /**
  * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI
  *
- * Copyright (C) 2012-2013 Texas Instruments Incorporated - http://www.ti.com
+ * Copyright (C) 2012-2013 Texas Instruments Incorporated - https://www.ti.com
  * Author: Keshava Munegowda <keshava_mgowda@ti.com>
  * Author: Roger Quadros <rogerq@ti.com>
  */
@@ -199,6 +199,8 @@ static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
  * usbtll_omap_probe - initialize TI-based HCDs
  *
  * Allocates basic resources for this USB host controller.
+ *
+ * @pdev: Pointer to this device's platform device structure
  */
 static int usbtll_omap_probe(struct platform_device *pdev)
 {
index 26c7b63..abaab54 100644 (file)
@@ -96,7 +96,7 @@ struct rave_sp_deframer {
  * @data:      Buffer to store reply payload in
  * @code:      Expected reply code
  * @ackid:     Expected reply ACK ID
- * @completion: Successful reply reception completion
+ * @received:   Successful reply reception completion
  */
 struct rave_sp_reply {
        size_t length;
index 232de50..e25407e 100644 (file)
@@ -44,6 +44,9 @@ static bool rn5t618_volatile_reg(struct device *dev, unsigned int reg)
        case RN5T618_INTMON:
        case RN5T618_RTC_CTRL1 ... RN5T618_RTC_CTRL2:
        case RN5T618_RTC_SECONDS ... RN5T618_RTC_YEAR:
+       case RN5T618_CHGSTATE:
+       case RN5T618_CHGCTRL_IRR ... RN5T618_CHGERR_MONI:
+       case RN5T618_CONTROL ... RN5T618_CC_AVEREG0:
                return true;
        default:
                return false;
@@ -77,7 +80,7 @@ static const struct regmap_irq_chip rc5t619_irq_chip = {
        .mask_invert = true,
 };
 
-static struct rn5t618 *rn5t618_pm_power_off;
+static struct i2c_client *rn5t618_pm_power_off;
 static struct notifier_block rn5t618_restart_handler;
 
 static int rn5t618_irq_init(struct rn5t618 *rn5t618)
@@ -110,13 +113,38 @@ static int rn5t618_irq_init(struct rn5t618 *rn5t618)
 
 static void rn5t618_trigger_poweroff_sequence(bool repower)
 {
+       int ret;
+
        /* disable automatic repower-on */
-       regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_REPCNT,
-                          RN5T618_REPCNT_REPWRON,
-                          repower ? RN5T618_REPCNT_REPWRON : 0);
+       ret = i2c_smbus_read_byte_data(rn5t618_pm_power_off, RN5T618_REPCNT);
+       if (ret < 0)
+               goto err;
+
+       ret &= ~RN5T618_REPCNT_REPWRON;
+       if (repower)
+               ret |= RN5T618_REPCNT_REPWRON;
+
+       ret = i2c_smbus_write_byte_data(rn5t618_pm_power_off,
+                                       RN5T618_REPCNT, (u8)ret);
+       if (ret < 0)
+               goto err;
+
        /* start power-off sequence */
-       regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_SLPCNT,
-                          RN5T618_SLPCNT_SWPWROFF, RN5T618_SLPCNT_SWPWROFF);
+       ret = i2c_smbus_read_byte_data(rn5t618_pm_power_off, RN5T618_SLPCNT);
+       if (ret < 0)
+               goto err;
+
+       ret |= RN5T618_SLPCNT_SWPWROFF;
+
+       ret = i2c_smbus_write_byte_data(rn5t618_pm_power_off,
+                                       RN5T618_SLPCNT, (u8)ret);
+       if (ret < 0)
+               goto err;
+
+       return;
+
+err:
+       dev_alert(&rn5t618_pm_power_off->dev, "Failed to shutdown (err = %d)\n", ret);
 }
 
 static void rn5t618_power_off(void)
@@ -189,7 +217,7 @@ static int rn5t618_i2c_probe(struct i2c_client *i2c)
                return ret;
        }
 
-       rn5t618_pm_power_off = priv;
+       rn5t618_pm_power_off = i2c;
        if (of_device_is_system_power_controller(i2c->dev.of_node)) {
                if (!pm_power_off)
                        pm_power_off = rn5t618_power_off;
@@ -211,9 +239,7 @@ static int rn5t618_i2c_probe(struct i2c_client *i2c)
 
 static int rn5t618_i2c_remove(struct i2c_client *i2c)
 {
-       struct rn5t618 *priv = i2c_get_clientdata(i2c);
-
-       if (priv == rn5t618_pm_power_off) {
+       if (i2c == rn5t618_pm_power_off) {
                rn5t618_pm_power_off = NULL;
                pm_power_off = NULL;
        }
index 4a09ce9..d15b3e7 100644 (file)
@@ -241,13 +241,13 @@ static int si476x_core_parse_and_nag_about_error(struct si476x_core *core)
 /**
  * si476x_core_send_command() - sends a command to si476x and waits its
  * response
- * @core:    si476x_device structure for the device we are
+ * @core:     si476x_device structure for the device we are
  *            communicating with
  * @command:  command id
  * @args:     command arguments we are sending
  * @argn:     actual size of @args
- * @response: buffer to place the expected response from the device
- * @respn:    actual size of @response
+ * @resp:     buffer to place the expected response from the device
+ * @respn:    actual size of @resp
  * @usecs:    amount of time to wait before reading the response (in
  *            usecs)
  *
@@ -496,7 +496,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_get_property);
  *                             enable 1MOhm pulldown
  *      SI476X_DFS_DAUDIO    - set the pin to be a part of digital
  *                             audio interface
- * @dout - DOUT pin function configuration:
+ * @dout: - DOUT pin function configuration:
  *      SI476X_DOUT_NOOP       - do not modify the behaviour
  *      SI476X_DOUT_TRISTATE   - put the pin in tristate condition,
  *                               enable 1MOhm pulldown
@@ -504,7 +504,7 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_get_property);
  *                               port 1
  *      SI476X_DOUT_I2S_INPUT  - set this pin to be digital in on I2S
  *                               port 1
- * @xout - XOUT pin function configuration:
+ * @xout: - XOUT pin function configuration:
  *     SI476X_XOUT_NOOP        - do not modify the behaviour
  *      SI476X_XOUT_TRISTATE    - put the pin in tristate condition,
  *                                enable 1MOhm pulldown
@@ -540,25 +540,25 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_dig_audio_pin_cfg);
 
 /**
  * si476x_cmd_zif_pin_cfg - send 'ZIF_PIN_CFG_COMMAND'
- * @core - device to send the command to
- * @iqclk - IQCL pin function configuration:
+ * @core: - device to send the command to
+ * @iqclk: - IQCL pin function configuration:
  *       SI476X_IQCLK_NOOP     - do not modify the behaviour
  *       SI476X_IQCLK_TRISTATE - put the pin in tristate condition,
  *                               enable 1MOhm pulldown
  *       SI476X_IQCLK_IQ       - set pin to be a part of I/Q interace
  *                               in master mode
- * @iqfs - IQFS pin function configuration:
+ * @iqfs: - IQFS pin function configuration:
  *       SI476X_IQFS_NOOP     - do not modify the behaviour
  *       SI476X_IQFS_TRISTATE - put the pin in tristate condition,
  *                              enable 1MOhm pulldown
  *       SI476X_IQFS_IQ       - set pin to be a part of I/Q interace
  *                              in master mode
- * @iout - IOUT pin function configuration:
+ * @iout: - IOUT pin function configuration:
  *       SI476X_IOUT_NOOP     - do not modify the behaviour
  *       SI476X_IOUT_TRISTATE - put the pin in tristate condition,
  *                              enable 1MOhm pulldown
  *       SI476X_IOUT_OUTPUT   - set pin to be I out
- * @qout - QOUT pin function configuration:
+ * @qout: - QOUT pin function configuration:
  *       SI476X_QOUT_NOOP     - do not modify the behaviour
  *       SI476X_QOUT_TRISTATE - put the pin in tristate condition,
  *                              enable 1MOhm pulldown
@@ -590,29 +590,29 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_zif_pin_cfg);
 /**
  * si476x_cmd_ic_link_gpo_ctl_pin_cfg - send
  * 'IC_LINK_GPIO_CTL_PIN_CFG' comand to the device
- * @core - device to send the command to
- * @icin - ICIN pin function configuration:
+ * @core: - device to send the command to
+ * @icin: - ICIN pin function configuration:
  *      SI476X_ICIN_NOOP      - do not modify the behaviour
  *      SI476X_ICIN_TRISTATE  - put the pin in tristate condition,
  *                              enable 1MOhm pulldown
  *      SI476X_ICIN_GPO1_HIGH - set pin to be an output, drive it high
  *      SI476X_ICIN_GPO1_LOW  - set pin to be an output, drive it low
  *      SI476X_ICIN_IC_LINK   - set the pin to be a part of Inter-Chip link
- * @icip - ICIP pin function configuration:
+ * @icip: - ICIP pin function configuration:
  *      SI476X_ICIP_NOOP      - do not modify the behaviour
  *      SI476X_ICIP_TRISTATE  - put the pin in tristate condition,
  *                              enable 1MOhm pulldown
  *      SI476X_ICIP_GPO1_HIGH - set pin to be an output, drive it high
  *      SI476X_ICIP_GPO1_LOW  - set pin to be an output, drive it low
  *      SI476X_ICIP_IC_LINK   - set the pin to be a part of Inter-Chip link
- * @icon - ICON pin function configuration:
+ * @icon: - ICON pin function configuration:
  *      SI476X_ICON_NOOP     - do not modify the behaviour
  *      SI476X_ICON_TRISTATE - put the pin in tristate condition,
  *                             enable 1MOhm pulldown
  *      SI476X_ICON_I2S      - set the pin to be a part of audio
  *                             interface in slave mode (DCLK)
  *      SI476X_ICON_IC_LINK  - set the pin to be a part of Inter-Chip link
- * @icop - ICOP pin function configuration:
+ * @icop: - ICOP pin function configuration:
  *      SI476X_ICOP_NOOP     - do not modify the behaviour
  *      SI476X_ICOP_TRISTATE - put the pin in tristate condition,
  *                             enable 1MOhm pulldown
@@ -647,8 +647,8 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_ic_link_gpo_ctl_pin_cfg);
 /**
  * si476x_cmd_ana_audio_pin_cfg - send 'ANA_AUDIO_PIN_CFG' to the
  * device
- * @core - device to send the command to
- * @lrout - LROUT pin function configuration:
+ * @core: - device to send the command to
+ * @lrout: - LROUT pin function configuration:
  *       SI476X_LROUT_NOOP     - do not modify the behaviour
  *       SI476X_LROUT_TRISTATE - put the pin in tristate condition,
  *                               enable 1MOhm pulldown
@@ -675,15 +675,15 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_ana_audio_pin_cfg);
 
 /**
  * si476x_cmd_intb_pin_cfg - send 'INTB_PIN_CFG' command to the device
- * @core - device to send the command to
- * @intb - INTB pin function configuration:
+ * @core: - device to send the command to
+ * @intb: - INTB pin function configuration:
  *      SI476X_INTB_NOOP     - do not modify the behaviour
  *      SI476X_INTB_TRISTATE - put the pin in tristate condition,
  *                             enable 1MOhm pulldown
  *      SI476X_INTB_DAUDIO   - set pin to be a part of digital
  *                             audio interface in slave mode
  *      SI476X_INTB_IRQ      - set pin to be an interrupt request line
- * @a1 - A1 pin function configuration:
+ * @a1: - A1 pin function configuration:
  *      SI476X_A1_NOOP     - do not modify the behaviour
  *      SI476X_A1_TRISTATE - put the pin in tristate condition,
  *                           enable 1MOhm pulldown
@@ -728,14 +728,10 @@ static int si476x_core_cmd_intb_pin_cfg_a20(struct si476x_core *core,
 /**
  * si476x_cmd_am_rsq_status - send 'AM_RSQ_STATUS' command to the
  * device
- * @core  - device to send the command to
- * @rsqack - if set command clears RSQINT, SNRINT, SNRLINT, RSSIHINT,
- *           RSSSILINT, BLENDINT, MULTHINT and MULTLINT
- * @attune - when set the values in the status report are the values
- *           that were calculated at tune
- * @cancel - abort ongoing seek/tune opertation
- * @stcack - clear the STCINT bin in status register
- * @report - all signal quality information retured by the command
+ * @core:  - device to send the command to
+ * @rsqargs: - pointer to a structure containing a group of sub-args
+ *             relevant to sending the RSQ status command
+ * @report: - all signal quality information retured by the command
  *           (if NULL then the output of the command is ignored)
  *
  * Function returns 0 on success and negative error code on failure
@@ -862,9 +858,9 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_am_acf_status);
 /**
  * si476x_cmd_fm_seek_start - send 'FM_SEEK_START' command to the
  * device
- * @core  - device to send the command to
- * @seekup - if set the direction of the search is 'up'
- * @wrap   - if set seek wraps when hitting band limit
+ * @core:  - device to send the command to
+ * @seekup: - if set the direction of the search is 'up'
+ * @wrap:   - if set seek wraps when hitting band limit
  *
  * This function begins search for a valid station. The station is
  * considered valid when 'FM_VALID_SNR_THRESHOLD' and
@@ -890,12 +886,14 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_seek_start);
 /**
  * si476x_cmd_fm_rds_status - send 'FM_RDS_STATUS' command to the
  * device
- * @core - device to send the command to
- * @status_only - if set the data is not removed from RDSFIFO,
+ * @core: - device to send the command to
+ * @status_only: - if set the data is not removed from RDSFIFO,
  *                RDSFIFOUSED is not decremented and data in all the
  *                rest RDS data contains the last valid info received
- * @mtfifo if set the command clears RDS receive FIFO
- * @intack if set the command clards the RDSINT bit.
+ * @mtfifo: if set the command clears RDS receive FIFO
+ * @intack: if set the command clards the RDSINT bit.
+ * @report: - all signal quality information retured by the command
+ *           (if NULL then the output of the command is ignored)
  *
  * Function returns 0 on success and negative error code on failure
  */
@@ -1036,9 +1034,9 @@ EXPORT_SYMBOL_GPL(si476x_core_cmd_fm_phase_div_status);
 /**
  * si476x_cmd_am_seek_start - send 'FM_SEEK_START' command to the
  * device
- * @core  - device to send the command to
- * @seekup - if set the direction of the search is 'up'
- * @wrap   - if set seek wraps when hitting band limit
+ * @core:  - device to send the command to
+ * @seekup: - if set the direction of the search is 'up'
+ * @wrap:   - if set seek wraps when hitting band limit
  *
  * This function begins search for a valid station. The station is
  * considered valid when 'FM_VALID_SNR_THRESHOLD' and
index c8d28b8..c1d7b84 100644 (file)
@@ -534,6 +534,11 @@ static irqreturn_t si476x_core_interrupt(int irq, void *dev)
 /**
  * si476x_firmware_version_to_revision()
  * @core: Core device structure
+ * @func: Selects the boot function of the device:
+ *         *_BOOTLOADER  - Boot loader
+ *         *_FM_RECEIVER - FM receiver
+ *         *_AM_RECEIVER - AM receiver
+ *         *_WB_RECEIVER - Weatherband receiver
  * @major:  Firmware major number
  * @minor1: Firmware first minor number
  * @minor2: Firmware second minor number
@@ -583,7 +588,7 @@ static int si476x_core_fwver_to_revision(struct si476x_core *core,
                        goto unknown_revision;
                }
        case SI476X_FUNC_BOOTLOADER:
-       default:                /* FALLTHROUG */
+       default:                /* FALLTHROUGH */
                BUG();
                return -1;
        }
diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c
deleted file mode 100644 (file)
index 57b792e..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * TI SMSC MFD Driver
- *
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
- *
- * Author: Sourav Poddar <sourav.poddar@ti.com>
- *
- *  This program is free software; you can redistribute it and/or modify it
- *  under  the terms of the GNU General  Public License as published by the
- *  Free Software Foundation;  GPL v2.
- *
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
-#include <linux/irq.h>
-#include <linux/regmap.h>
-#include <linux/err.h>
-#include <linux/mfd/core.h>
-#include <linux/mfd/smsc.h>
-#include <linux/of_platform.h>
-
-static const struct regmap_config smsc_regmap_config = {
-               .reg_bits = 8,
-               .val_bits = 8,
-               .max_register = SMSC_VEN_ID_H,
-               .cache_type = REGCACHE_RBTREE,
-};
-
-static int smsc_i2c_probe(struct i2c_client *i2c,
-                       const struct i2c_device_id *id)
-{
-       struct smsc *smsc;
-       int devid, rev, venid_l, venid_h;
-       int ret;
-
-       smsc = devm_kzalloc(&i2c->dev, sizeof(*smsc), GFP_KERNEL);
-       if (!smsc)
-               return -ENOMEM;
-
-       smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
-       if (IS_ERR(smsc->regmap))
-               return PTR_ERR(smsc->regmap);
-
-       i2c_set_clientdata(i2c, smsc);
-       smsc->dev = &i2c->dev;
-
-#ifdef CONFIG_OF
-       of_property_read_u32(i2c->dev.of_node, "clock", &smsc->clk);
-#endif
-
-       regmap_read(smsc->regmap, SMSC_DEV_ID, &devid);
-       regmap_read(smsc->regmap, SMSC_DEV_REV, &rev);
-       regmap_read(smsc->regmap, SMSC_VEN_ID_L, &venid_l);
-       regmap_read(smsc->regmap, SMSC_VEN_ID_H, &venid_h);
-
-       dev_info(&i2c->dev, "SMSCxxx devid: %02x rev: %02x venid: %02x\n",
-               devid, rev, (venid_h << 8) | venid_l);
-
-       ret = regmap_write(smsc->regmap, SMSC_CLK_CTRL, smsc->clk);
-       if (ret)
-               return ret;
-
-#ifdef CONFIG_OF
-       if (i2c->dev.of_node)
-               ret = devm_of_platform_populate(&i2c->dev);
-#endif
-
-       return ret;
-}
-
-static const struct i2c_device_id smsc_i2c_id[] = {
-       { "smscece1099", 0},
-       {},
-};
-
-static struct i2c_driver smsc_i2c_driver = {
-       .driver = {
-                  .name = "smsc",
-       },
-       .probe = smsc_i2c_probe,
-       .id_table = smsc_i2c_id,
-};
-builtin_i2c_driver(smsc_i2c_driver);
index 33336cd..f8a8b91 100644 (file)
@@ -7,7 +7,9 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/mfd/core.h>
+#include <linux/mfd/sc27xx-pmic.h>
 #include <linux/of_device.h>
+#include <linux/of_platform.h>
 #include <linux/regmap.h>
 #include <linux/spi/spi.h>
 #include <uapi/linux/usb/charger.h>
@@ -93,73 +95,6 @@ enum usb_charger_type sprd_pmic_detect_charger_type(struct device *dev)
 }
 EXPORT_SYMBOL_GPL(sprd_pmic_detect_charger_type);
 
-static const struct mfd_cell sprd_pmic_devs[] = {
-       {
-               .name = "sc27xx-wdt",
-               .of_compatible = "sprd,sc2731-wdt",
-       }, {
-               .name = "sc27xx-rtc",
-               .of_compatible = "sprd,sc2731-rtc",
-       }, {
-               .name = "sc27xx-charger",
-               .of_compatible = "sprd,sc2731-charger",
-       }, {
-               .name = "sc27xx-chg-timer",
-               .of_compatible = "sprd,sc2731-chg-timer",
-       }, {
-               .name = "sc27xx-fast-chg",
-               .of_compatible = "sprd,sc2731-fast-chg",
-       }, {
-               .name = "sc27xx-chg-wdt",
-               .of_compatible = "sprd,sc2731-chg-wdt",
-       }, {
-               .name = "sc27xx-typec",
-               .of_compatible = "sprd,sc2731-typec",
-       }, {
-               .name = "sc27xx-flash",
-               .of_compatible = "sprd,sc2731-flash",
-       }, {
-               .name = "sc27xx-eic",
-               .of_compatible = "sprd,sc2731-eic",
-       }, {
-               .name = "sc27xx-efuse",
-               .of_compatible = "sprd,sc2731-efuse",
-       }, {
-               .name = "sc27xx-thermal",
-               .of_compatible = "sprd,sc2731-thermal",
-       }, {
-               .name = "sc27xx-adc",
-               .of_compatible = "sprd,sc2731-adc",
-       }, {
-               .name = "sc27xx-audio-codec",
-               .of_compatible = "sprd,sc2731-audio-codec",
-       }, {
-               .name = "sc27xx-regulator",
-               .of_compatible = "sprd,sc2731-regulator",
-       }, {
-               .name = "sc27xx-vibrator",
-               .of_compatible = "sprd,sc2731-vibrator",
-       }, {
-               .name = "sc27xx-keypad-led",
-               .of_compatible = "sprd,sc2731-keypad-led",
-       }, {
-               .name = "sc27xx-bltc",
-               .of_compatible = "sprd,sc2731-bltc",
-       }, {
-               .name = "sc27xx-fgu",
-               .of_compatible = "sprd,sc2731-fgu",
-       }, {
-               .name = "sc27xx-7sreset",
-               .of_compatible = "sprd,sc2731-7sreset",
-       }, {
-               .name = "sc27xx-poweroff",
-               .of_compatible = "sprd,sc2731-poweroff",
-       }, {
-               .name = "sc27xx-syscon",
-               .of_compatible = "sprd,sc2731-syscon",
-       },
-};
-
 static int sprd_pmic_spi_write(void *context, const void *data, size_t count)
 {
        struct device *dev = context;
@@ -250,10 +185,8 @@ static int sprd_pmic_probe(struct spi_device *spi)
                return -ENOMEM;
 
        ddata->irq_chip.irqs = ddata->irqs;
-       for (i = 0; i < pdata->num_irqs; i++) {
-               ddata->irqs[i].reg_offset = i / pdata->num_irqs;
-               ddata->irqs[i].mask = BIT(i % pdata->num_irqs);
-       }
+       for (i = 0; i < pdata->num_irqs; i++)
+               ddata->irqs[i].mask = BIT(i);
 
        ret = devm_regmap_add_irq_chip(&spi->dev, ddata->regmap, ddata->irq,
                                       IRQF_ONESHOT | IRQF_NO_SUSPEND, 0,
@@ -263,12 +196,9 @@ static int sprd_pmic_probe(struct spi_device *spi)
                return ret;
        }
 
-       ret = devm_mfd_add_devices(&spi->dev, PLATFORM_DEVID_AUTO,
-                                  sprd_pmic_devs, ARRAY_SIZE(sprd_pmic_devs),
-                                  NULL, 0,
-                                  regmap_irq_get_domain(ddata->irq_data));
+       ret = devm_of_platform_populate(&spi->dev);
        if (ret) {
-               dev_err(&spi->dev, "Failed to register device %d\n", ret);
+               dev_err(&spi->dev, "Failed to populate sub-devices %d\n", ret);
                return ret;
        }
 
index a00f99f..746e51a 100644 (file)
@@ -17,6 +17,7 @@ static const struct regmap_config stm32_lptimer_regmap_cfg = {
        .val_bits = 32,
        .reg_stride = sizeof(u32),
        .max_register = STM32_LPTIM_MAX_REGISTER,
+       .fast_io = true,
 };
 
 static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata)
index 3a97816..75859e4 100644 (file)
@@ -101,12 +101,14 @@ static struct syscon *of_syscon_register(struct device_node *np, bool check_clk)
                }
        }
 
-       syscon_config.name = of_node_full_name(np);
+       syscon_config.name = kasprintf(GFP_KERNEL, "%pOFn@%llx", np,
+                                      (u64)res.start);
        syscon_config.reg_stride = reg_io_width;
        syscon_config.val_bits = reg_io_width * 8;
        syscon_config.max_register = resource_size(&res) - reg_io_width;
 
        regmap = regmap_init_mmio(NULL, base, &syscon_config);
+       kfree(syscon_config.name);
        if (IS_ERR(regmap)) {
                pr_err("regmap init failed\n");
                ret = PTR_ERR(regmap);
index 67c9995..7882a37 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/mfd/tc3589x.h>
 #include <linux/err.h>
 
-/**
+/*
  * enum tc3589x_version - indicates the TC3589x version
  */
 enum tc3589x_version {
index 926c289..0e6e253 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * TI Touch Screen / ADC MFD driver
  *
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
index 65fcc58..7e7dbee 100644 (file)
@@ -404,7 +404,6 @@ static void tps65010_work(struct work_struct *work)
        tps65010_interrupt(tps);
 
        if (test_and_clear_bit(FLAG_VBUS_CHANGED, &tps->flags)) {
-               int     status;
                u8      chgconfig, tmp;
 
                chgconfig = i2c_smbus_read_byte_data(tps->client,
@@ -415,8 +414,8 @@ static void tps65010_work(struct work_struct *work)
                else if (tps->vbus >= 100)
                        chgconfig |= TPS_VBUS_CHARGING;
 
-               status = i2c_smbus_write_byte_data(tps->client,
-                               TPS_CHGCONFIG, chgconfig);
+               i2c_smbus_write_byte_data(tps->client,
+                                         TPS_CHGCONFIG, chgconfig);
 
                /* vbus update fails unless VBUS is connected! */
                tmp = i2c_smbus_read_byte_data(tps->client, TPS_CHGCONFIG);
index 43119a6..341466e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
  *     Andrew F. Davis <afd@ti.com>
  *
  * This program is free software; you can redistribute it and/or
index 7566ce4..2d9c282 100644 (file)
@@ -3,7 +3,7 @@
  *
  * TPS65217 chip family multi-function driver
  *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -205,7 +205,7 @@ EXPORT_SYMBOL_GPL(tps65217_reg_read);
 /**
  * tps65217_reg_write: Write a single tps65217 register.
  *
- * @tps65217: Device to write to.
+ * @tps: Device to write to.
  * @reg: Register to write to.
  * @val: Value to write.
  * @level: Password protected level
@@ -250,7 +250,7 @@ EXPORT_SYMBOL_GPL(tps65217_reg_write);
 /**
  * tps65217_update_bits: Modify bits w.r.t mask, val and level.
  *
- * @tps65217: Device to write to.
+ * @tps: Device to write to.
  * @reg: Register to read-write to.
  * @mask: Mask.
  * @val: Value to write.
index a62ea4c..167e9fc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Driver for TPS65218 Integrated power management chipsets
  *
- * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version 2 as
@@ -48,7 +48,7 @@ static const struct mfd_cell tps65218_cells[] = {
 /**
  * tps65218_reg_write: Write a single tps65218 register.
  *
- * @tps65218: Device to write to.
+ * @tps: Device to write to.
  * @reg: Register to write to.
  * @val: Value to write.
  * @level: Password protected level
@@ -79,7 +79,7 @@ EXPORT_SYMBOL_GPL(tps65218_reg_write);
 /**
  * tps65218_update_bits: Modify bits w.r.t mask, val and level.
  *
- * @tps65218: Device to write to.
+ * @tps: Device to write to.
  * @reg: Register to read-write to.
  * @mask: Mask.
  * @val: Value to write.
index c8aadd3..c365977 100644 (file)
@@ -309,18 +309,19 @@ static const struct irq_domain_ops tps6586x_domain_ops = {
 static irqreturn_t tps6586x_irq(int irq, void *data)
 {
        struct tps6586x *tps6586x = data;
-       u32 acks;
+       uint32_t acks;
+       __le32 val;
        int ret = 0;
 
        ret = tps6586x_reads(tps6586x->dev, TPS6586X_INT_ACK1,
-                            sizeof(acks), (uint8_t *)&acks);
+                            sizeof(acks), (uint8_t *)&val);
 
        if (ret < 0) {
                dev_err(tps6586x->dev, "failed to read interrupt status\n");
                return IRQ_NONE;
        }
 
-       acks = le32_to_cpu(acks);
+       acks = le32_to_cpu(val);
 
        while (acks) {
                int i = __ffs(acks);
index f33567b..b55b1d5 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Core functions for TI TPS65912x PMICs
  *
- * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
  *     Andrew F. Davis <afd@ti.com>
  *
  * This program is free software; you can redistribute it and/or
index 785d19f..f7c22ea 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * I2C access driver for TI TPS65912x PMICs
  *
- * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
  *     Andrew F. Davis <afd@ti.com>
  *
  * This program is free software; you can redistribute it and/or
index f78be03..21a8d6a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * SPI access driver for TI TPS65912x PMICs
  *
- * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
  *     Andrew F. Davis <afd@ti.com>
  *
  * This program is free software; you can redistribute it and/or
index 910a304..ab41743 100644 (file)
@@ -477,7 +477,7 @@ static void twl4030_sih_bus_sync_unlock(struct irq_data *data)
 
        if (agent->imr_change_pending) {
                union {
-                       u32     word;
+                       __le32  word;
                        u8      bytes[4];
                } imr;
 
@@ -561,7 +561,7 @@ static inline int sih_read_isr(const struct sih *sih)
        int status;
        union {
                u8 bytes[4];
-               u32 word;
+               __le32 word;
        } isr;
 
        /* FIXME need retry-on-error ... */
index 02f879b..b0344e5 100644 (file)
@@ -114,6 +114,8 @@ static int wm831x_reg_locked(struct wm831x *wm831x, unsigned short reg)
  * The WM831x has a user key preventing writes to particularly
  * critical registers.  This function locks those registers,
  * allowing writes to them.
+ *
+ * @wm831x: pointer to local driver data structure
  */
 void wm831x_reg_lock(struct wm831x *wm831x)
 {
@@ -140,6 +142,8 @@ EXPORT_SYMBOL_GPL(wm831x_reg_lock);
  * The WM831x has a user key preventing writes to particularly
  * critical registers.  This function locks those registers,
  * preventing spurious writes.
+ *
+ * @wm831x: pointer to local driver data structure
  */
 int wm831x_reg_unlock(struct wm831x *wm831x)
 {
index 42b1650..fbc77b2 100644 (file)
@@ -131,6 +131,8 @@ EXPORT_SYMBOL_GPL(wm8350_block_write);
  * The WM8350 has a hardware lock which can be used to prevent writes to
  * some registers (generally those which can cause particularly serious
  * problems if misused).  This function enables that lock.
+ *
+ * @wm8350: pointer to local driver data structure
  */
 int wm8350_reg_lock(struct wm8350 *wm8350)
 {
@@ -160,6 +162,8 @@ EXPORT_SYMBOL_GPL(wm8350_reg_lock);
  * problems if misused).  This function disables that lock so updates
  * can be performed.  For maximum safety this should be done only when
  * required.
+ *
+ * @wm8350: pointer to local driver data structure
  */
 int wm8350_reg_unlock(struct wm8350 *wm8350)
 {
index 3055d6f..0fe32a0 100644 (file)
@@ -108,6 +108,8 @@ static const struct regmap_config wm8400_regmap_config = {
 /**
  * wm8400_reset_codec_reg_cache - Reset cached codec registers to
  * their default values.
+ *
+ * @wm8400: pointer to local driver data structure
  */
 void wm8400_reset_codec_reg_cache(struct wm8400 *wm8400)
 {
index 31e43a2..cddaa43 100644 (file)
@@ -130,7 +130,7 @@ static inline struct bonding *__get_bond_by_port(struct port *port)
 
 /**
  * __get_first_agg - get the first aggregator in the bond
- * @bond: the bond we're looking at
+ * @port: the port we're looking at
  *
  * Return the aggregator of the first slave in @bond, or %NULL if it can't be
  * found.
@@ -1626,7 +1626,7 @@ static int agg_device_up(const struct aggregator *agg)
 
 /**
  * ad_agg_selection_logic - select an aggregation group for a team
- * @aggregator: the aggregator we're looking at
+ * @agg: the aggregator we're looking at
  * @update_slave_arr: Does slave array need update?
  *
  * It is assumed that only one aggregator may be selected for a team.
@@ -1810,7 +1810,7 @@ static void ad_initialize_agg(struct aggregator *aggregator)
 
 /**
  * ad_initialize_port - initialize a given port's parameters
- * @aggregator: the aggregator we're looking at
+ * @port: the port we're looking at
  * @lacp_fast: boolean. whether fast periodic should be used
  */
 static void ad_initialize_port(struct port *port, int lacp_fast)
@@ -1967,6 +1967,7 @@ static void ad_marker_response_received(struct bond_marker *marker,
 /**
  * bond_3ad_initiate_agg_selection - initate aggregator selection
  * @bond: bonding struct
+ * @timeout: timeout value to set
  *
  * Set the aggregation selection timer, to initiate an agg selection in
  * the very near future.  Called during first initialization, and during
@@ -2259,7 +2260,7 @@ void bond_3ad_update_ad_actor_settings(struct bonding *bond)
 
 /**
  * bond_3ad_state_machine_handler - handle state machines timeout
- * @bond: bonding struct to work on
+ * @work: work context to fetch bonding struct to work on from
  *
  * The state machine handling concept in this module is to check every tick
  * which state machine should operate any function. The execution order is
@@ -2500,7 +2501,7 @@ void bond_3ad_adapter_speed_duplex_changed(struct slave *slave)
 /**
  * bond_3ad_handle_link_change - handle a slave's link status change indication
  * @slave: slave struct to work on
- * @status: whether the link is now up or down
+ * @link: whether the link is now up or down
  *
  * Handle reselection of aggregator (if needed) for this port.
  */
@@ -2551,7 +2552,7 @@ void bond_3ad_handle_link_change(struct slave *slave, char link)
 
 /**
  * bond_3ad_set_carrier - set link state for bonding master
- * @bond - bonding structure
+ * @bond: bonding structure
  *
  * if we have an active aggregator, we're up, if not, we're down.
  * Presumes that we cannot have an active aggregator if there are
@@ -2664,7 +2665,7 @@ int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond,
 
 /**
  * bond_3ad_update_lacp_rate - change the lacp rate
- * @bond - bonding struct
+ * @bond: bonding struct
  *
  * When modify lacp_rate parameter via sysfs,
  * update actor_oper_port_state of each port.
index 095ea51..4e1b7de 100644 (file)
@@ -1206,8 +1206,8 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav
 
 /**
  * alb_set_mac_address
- * @bond:
- * @addr:
+ * @bond: bonding we're working on
+ * @addr: MAC address to set
  *
  * In TLB mode all slaves are configured to the bond's hw address, but set
  * their dev_addr field to different addresses (based on their permanent hw
index 5ad43aa..415a37e 100644 (file)
@@ -322,6 +322,7 @@ netdev_tx_t bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
 /**
  * bond_vlan_rx_add_vid - Propagates adding an id to slaves
  * @bond_dev: bonding net device that got called
+ * @proto: network protocol ID
  * @vid: vlan id being added
  */
 static int bond_vlan_rx_add_vid(struct net_device *bond_dev,
@@ -355,6 +356,7 @@ unwind:
 /**
  * bond_vlan_rx_kill_vid - Propagates deleting an id to slaves
  * @bond_dev: bonding net device that got called
+ * @proto: network protocol ID
  * @vid: vlan id being removed
  */
 static int bond_vlan_rx_kill_vid(struct net_device *bond_dev,
@@ -948,7 +950,7 @@ static bool bond_should_notify_peers(struct bonding *bond)
 /**
  * change_active_interface - change the active slave into the specified one
  * @bond: our bonding struct
- * @new: the new slave to make the active one
+ * @new_active: the new slave to make the active one
  *
  * Set the new slave to the bond's settings and unset them on the old
  * curr_active_slave.
@@ -2205,7 +2207,8 @@ static int bond_release_and_destroy(struct net_device *bond_dev,
        int ret;
 
        ret = __bond_release_one(bond_dev, slave_dev, false, true);
-       if (ret == 0 && !bond_has_slaves(bond)) {
+       if (ret == 0 && !bond_has_slaves(bond) &&
+           bond_dev->reg_state != NETREG_UNREGISTERING) {
                bond_dev->priv_flags |= IFF_DISABLE_NETPOLL;
                netdev_info(bond_dev, "Destroying bond\n");
                bond_remove_proc_entry(bond);
@@ -4552,13 +4555,23 @@ static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return ret;
 }
 
+static u32 bond_mode_bcast_speed(struct slave *slave, u32 speed)
+{
+       if (speed == 0 || speed == SPEED_UNKNOWN)
+               speed = slave->speed;
+       else
+               speed = min(speed, slave->speed);
+
+       return speed;
+}
+
 static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev,
                                           struct ethtool_link_ksettings *cmd)
 {
        struct bonding *bond = netdev_priv(bond_dev);
-       unsigned long speed = 0;
        struct list_head *iter;
        struct slave *slave;
+       u32 speed = 0;
 
        cmd->base.duplex = DUPLEX_UNKNOWN;
        cmd->base.port = PORT_OTHER;
@@ -4570,8 +4583,13 @@ static int bond_ethtool_get_link_ksettings(struct net_device *bond_dev,
         */
        bond_for_each_slave(bond, slave, iter) {
                if (bond_slave_can_tx(slave)) {
-                       if (slave->speed != SPEED_UNKNOWN)
-                               speed += slave->speed;
+                       if (slave->speed != SPEED_UNKNOWN) {
+                               if (BOND_MODE(bond) == BOND_MODE_BROADCAST)
+                                       speed = bond_mode_bcast_speed(slave,
+                                                                     speed);
+                               else
+                                       speed += slave->speed;
+                       }
                        if (cmd->base.duplex == DUPLEX_UNKNOWN &&
                            slave->duplex != DUPLEX_UNKNOWN)
                                cmd->base.duplex = slave->duplex;
index ef1c315..bd0ada4 100644 (file)
@@ -951,7 +951,7 @@ static struct net_device_stats *el3_get_stats(struct net_device *dev)
 static void update_stats(struct net_device *dev)
 {
        unsigned int ioaddr = dev->base_addr;
-       u8 rx, tx, up;
+       u8 up;
 
        pr_debug("%s: updating the statistics.\n", dev->name);
 
@@ -972,8 +972,8 @@ static void update_stats(struct net_device *dev)
        dev->stats.tx_packets                   += (up&0x30) << 4;
        /* Rx packets   */                         inb(ioaddr + 7);
        /* Tx deferrals */                         inb(ioaddr + 8);
-       rx                                       = inw(ioaddr + 10);
-       tx                                       = inw(ioaddr + 12);
+       /* rx */                                   inw(ioaddr + 10);
+       /* tx */                                   inw(ioaddr + 12);
 
        EL3WINDOW(4);
        /* BadSSD */                               inb(ioaddr + 12);
index aeae796..08db4c9 100644 (file)
@@ -898,6 +898,7 @@ static int ax_close(struct net_device *dev)
 /**
  * axnet_tx_timeout - handle transmit time out condition
  * @dev: network device which has apparently fallen asleep
+ * @txqueue: unused
  *
  * Called by kernel when device never acknowledges a transmit has
  * completed (or failed) - i.e. never posted a Tx related interrupt.
index 9934421..fb37816 100644 (file)
@@ -3715,11 +3715,11 @@ failed_mii_init:
 failed_irq:
 failed_init:
        fec_ptp_stop(pdev);
-       if (fep->reg_phy)
-               regulator_disable(fep->reg_phy);
 failed_reset:
        pm_runtime_put_noidle(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
+       if (fep->reg_phy)
+               regulator_disable(fep->reg_phy);
 failed_regulator:
        clk_disable_unprepare(fep->clk_ahb);
 failed_clk_ahb:
index a62ddd6..c0c8efe 100644 (file)
@@ -981,7 +981,7 @@ struct i40e_aqc_set_vsi_promiscuous_modes {
 #define I40E_AQC_SET_VSI_PROMISC_BROADCAST     0x04
 #define I40E_AQC_SET_VSI_DEFAULT               0x08
 #define I40E_AQC_SET_VSI_PROMISC_VLAN          0x10
-#define I40E_AQC_SET_VSI_PROMISC_TX            0x8000
+#define I40E_AQC_SET_VSI_PROMISC_RX_ONLY       0x8000
        __le16  seid;
        __le16  vlan_tag;
 #define I40E_AQC_SET_VSI_VLAN_VALID            0x8000
index afad5e9..6ab52cb 100644 (file)
@@ -1966,6 +1966,21 @@ i40e_status i40e_aq_set_phy_debug(struct i40e_hw *hw, u8 cmd_flags,
        return status;
 }
 
+/**
+ * i40e_is_aq_api_ver_ge
+ * @aq: pointer to AdminQ info containing HW API version to compare
+ * @maj: API major value
+ * @min: API minor value
+ *
+ * Assert whether current HW API version is greater/equal than provided.
+ **/
+static bool i40e_is_aq_api_ver_ge(struct i40e_adminq_info *aq, u16 maj,
+                                 u16 min)
+{
+       return (aq->api_maj_ver > maj ||
+               (aq->api_maj_ver == maj && aq->api_min_ver >= min));
+}
+
 /**
  * i40e_aq_add_vsi
  * @hw: pointer to the hw struct
@@ -2091,18 +2106,16 @@ i40e_status i40e_aq_set_vsi_unicast_promiscuous(struct i40e_hw *hw,
 
        if (set) {
                flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
-               if (rx_only_promisc &&
-                   (((hw->aq.api_maj_ver == 1) && (hw->aq.api_min_ver >= 5)) ||
-                    (hw->aq.api_maj_ver > 1)))
-                       flags |= I40E_AQC_SET_VSI_PROMISC_TX;
+               if (rx_only_promisc && i40e_is_aq_api_ver_ge(&hw->aq, 1, 5))
+                       flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
        }
 
        cmd->promiscuous_flags = cpu_to_le16(flags);
 
        cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
-       if (((hw->aq.api_maj_ver >= 1) && (hw->aq.api_min_ver >= 5)) ||
-           (hw->aq.api_maj_ver > 1))
-               cmd->valid_flags |= cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_TX);
+       if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5))
+               cmd->valid_flags |=
+                       cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
 
        cmd->seid = cpu_to_le16(seid);
        status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
@@ -2199,11 +2212,17 @@ enum i40e_status_code i40e_aq_set_vsi_uc_promisc_on_vlan(struct i40e_hw *hw,
        i40e_fill_default_direct_cmd_desc(&desc,
                                          i40e_aqc_opc_set_vsi_promiscuous_modes);
 
-       if (enable)
+       if (enable) {
                flags |= I40E_AQC_SET_VSI_PROMISC_UNICAST;
+               if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5))
+                       flags |= I40E_AQC_SET_VSI_PROMISC_RX_ONLY;
+       }
 
        cmd->promiscuous_flags = cpu_to_le16(flags);
        cmd->valid_flags = cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_UNICAST);
+       if (i40e_is_aq_api_ver_ge(&hw->aq, 1, 5))
+               cmd->valid_flags |=
+                       cpu_to_le16(I40E_AQC_SET_VSI_PROMISC_RX_ONLY);
        cmd->seid = cpu_to_le16(seid);
        cmd->vlan_tag = cpu_to_le16(vid | I40E_AQC_SET_VSI_VLAN_VALID);
 
index b539935..2e433fd 100644 (file)
@@ -15463,6 +15463,9 @@ static void i40e_remove(struct pci_dev *pdev)
        i40e_write_rx_ctl(hw, I40E_PFQF_HENA(0), 0);
        i40e_write_rx_ctl(hw, I40E_PFQF_HENA(1), 0);
 
+       while (test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
+               usleep_range(1000, 2000);
+
        /* no more scheduling of any task */
        set_bit(__I40E_SUSPENDED, pf->state);
        set_bit(__I40E_DOWN, pf->state);
index 7a6f2a0..9593aa4 100644 (file)
@@ -5142,6 +5142,8 @@ static int igc_probe(struct pci_dev *pdev,
        device_set_wakeup_enable(&adapter->pdev->dev,
                                 adapter->flags & IGC_FLAG_WOL_SUPPORTED);
 
+       igc_ptp_init(adapter);
+
        /* reset the hardware with the new settings */
        igc_reset(adapter);
 
@@ -5158,9 +5160,6 @@ static int igc_probe(struct pci_dev *pdev,
         /* carrier off reporting is important to ethtool even BEFORE open */
        netif_carrier_off(netdev);
 
-       /* do hw tstamp init after resetting */
-       igc_ptp_init(adapter);
-
        /* Check if Media Autosense is enabled */
        adapter->ei = *ei;
 
index e67d465..36c9992 100644 (file)
@@ -496,8 +496,6 @@ void igc_ptp_init(struct igc_adapter *adapter)
        adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;
        adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;
 
-       igc_ptp_reset(adapter);
-
        adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,
                                                &adapter->pdev->dev);
        if (IS_ERR(adapter->ptp_clock)) {
index 5975521..93c4cf7 100644 (file)
@@ -1226,8 +1226,8 @@ int otx2_config_npa(struct otx2_nic *pfvf)
        if (!hw->pool_cnt)
                return -EINVAL;
 
-       qset->pool = devm_kzalloc(pfvf->dev, sizeof(struct otx2_pool) *
-                                 hw->pool_cnt, GFP_KERNEL);
+       qset->pool = devm_kcalloc(pfvf->dev, hw->pool_cnt,
+                                 sizeof(struct otx2_pool), GFP_KERNEL);
        if (!qset->pool)
                return -ENOMEM;
 
index 13ba1a4..012925e 100644 (file)
 #define ESF_GZ_RX_PREFIX_NT_OR_INNER_L3_CLASS_WIDTH    \
                ESF_GZ_RX_PREFIX_HCLASS_NT_OR_INNER_L3_CLASS_WIDTH
 
+bool ef100_rx_buf_hash_valid(const u8 *prefix)
+{
+       return PREFIX_FIELD(prefix, RSS_HASH_VALID);
+}
+
 static bool check_fcs(struct efx_channel *channel, u32 *prefix)
 {
        u16 rxclass;
index f2f2668..fe45b36 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "net_driver.h"
 
+bool ef100_rx_buf_hash_valid(const u8 *prefix);
 void efx_ef100_ev_rx(struct efx_channel *channel, const efx_qword_t *p_event);
 void ef100_rx_write(struct efx_rx_queue *rx_queue);
 void __ef100_rx_packet(struct efx_channel *channel);
index a9808e8..daf0c00 100644 (file)
@@ -45,6 +45,14 @@ static inline void efx_rx_flush_packet(struct efx_channel *channel)
                                __ef100_rx_packet, __efx_rx_packet,
                                channel);
 }
+static inline bool efx_rx_buf_hash_valid(struct efx_nic *efx, const u8 *prefix)
+{
+       if (efx->type->rx_buf_hash_valid)
+               return INDIRECT_CALL_1(efx->type->rx_buf_hash_valid,
+                                      ef100_rx_buf_hash_valid,
+                                      prefix);
+       return true;
+}
 
 /* Maximum number of TCP segments we support for soft-TSO */
 #define EFX_TSO_MAX_SEGS       100
index 7bb7ecb..dcb741d 100644 (file)
@@ -1265,6 +1265,7 @@ struct efx_udp_tunnel {
  * @rx_write: Write RX descriptors and doorbell
  * @rx_defer_refill: Generate a refill reminder event
  * @rx_packet: Receive the queued RX buffer on a channel
+ * @rx_buf_hash_valid: Determine whether the RX prefix contains a valid hash
  * @ev_probe: Allocate resources for event queue
  * @ev_init: Initialise event queue on the NIC
  * @ev_fini: Deinitialise event queue on the NIC
@@ -1409,6 +1410,7 @@ struct efx_nic_type {
        void (*rx_write)(struct efx_rx_queue *rx_queue);
        void (*rx_defer_refill)(struct efx_rx_queue *rx_queue);
        void (*rx_packet)(struct efx_channel *channel);
+       bool (*rx_buf_hash_valid)(const u8 *prefix);
        int (*ev_probe)(struct efx_channel *channel);
        int (*ev_init)(struct efx_channel *channel);
        void (*ev_fini)(struct efx_channel *channel);
index fb77c7b..ef9bca9 100644 (file)
@@ -525,7 +525,8 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf,
                return;
        }
 
-       if (efx->net_dev->features & NETIF_F_RXHASH)
+       if (efx->net_dev->features & NETIF_F_RXHASH &&
+           efx_rx_buf_hash_valid(efx, eh))
                skb_set_hash(skb, efx_rx_buf_hash(efx, eh),
                             PKT_HASH_TYPE_L3);
        if (csum) {
index e9bf429..4eea340 100644 (file)
 #define KERNEL
 #include "h/smtstate.h"
 
-#ifndef        lint
-static const char ID_sccs[] = "@(#)cfm.c       2.18 98/10/06 (C) SK " ;
-#endif
-
 /*
  * FSM Macros
  */
@@ -208,7 +204,6 @@ void cfm(struct s_smc *smc, int event)
 {
        int     state ;         /* remember last state */
        int     cond ;
-       int     oldstate ;
 
        /* We will do the following: */
        /*  - compute the variable WC_Flag for every port (This is where */
@@ -222,7 +217,6 @@ void cfm(struct s_smc *smc, int event)
        /*  - change the portstates */
        cem_priv_state (smc, event);
 
-       oldstate = smc->mib.fddiSMTCF_State ;
        do {
                DB_CFM("CFM : state %s%s event %s",
                       smc->mib.fddiSMTCF_State & AFLAG ? "ACTIONS " : "",
@@ -250,18 +244,11 @@ void cfm(struct s_smc *smc, int event)
        if (cond != smc->mib.fddiSMTPeerWrapFlag)
                smt_srf_event(smc,SMT_COND_SMT_PEER_WRAP,0,cond) ;
 
-#if    0
        /*
-        * Don't send ever MAC_PATH_CHANGE events. Our MAC is hard-wired
+        * Don't ever send MAC_PATH_CHANGE events. Our MAC is hard-wired
         * to the primary path.
         */
-       /*
-        * path change
-        */
-       if (smc->mib.fddiSMTCF_State != oldstate) {
-               smt_srf_event(smc,SMT_EVENT_MAC_PATH_CHANGE,INDEX_MAC,0) ;
-       }
-#endif
+
 #endif /* no SLIM_SMT */
 
        /*
index 02966d1..4cbb145 100644 (file)
 #include <linux/bitrev.h>
 #include <linux/etherdevice.h>
 
-#ifndef        lint
-static const char ID_sccs[] = "@(#)fplustm.c   1.32 99/02/23 (C) SK " ;
-#endif
-
 #ifndef UNUSED
 #ifdef  lint
 #define UNUSED(x)      (x) = (x)
index 3412e0f..1070390 100644 (file)
  *
  ******************************************************************************/
 
-#ifndef        lint
-static char const ID_sccs[] = "@(#)hwmtm.c     1.40 99/05/31 (C) SK" ;
-#endif
-
 #define        HWMTM
 
 #ifndef FDDI
index b8c59d8..774a6e3 100644 (file)
 #define KERNEL
 #include "h/smtstate.h"
 
-#ifndef        lint
-static const char ID_sccs[] = "@(#)smt.c       2.43 98/11/23 (C) SK " ;
-#endif
-
 /*
  * FC in SMbuf
  */
@@ -1561,7 +1557,7 @@ u_long smt_get_tid(struct s_smc *smc)
        return tid & 0x3fffffffL;
 }
 
-
+#ifdef LITTLE_ENDIAN
 /*
  * table of parameter lengths
  */
@@ -1641,6 +1637,7 @@ static const struct smt_pdef {
 } ;
 
 #define N_SMT_PLEN     ARRAY_SIZE(smt_pdef)
+#endif
 
 int smt_check_para(struct s_smc *smc, struct smt_header        *sm,
                   const u_short list[])
index 15e87c0..5bca94c 100644 (file)
@@ -106,12 +106,21 @@ static void ipvlan_port_destroy(struct net_device *dev)
        kfree(port);
 }
 
+#define IPVLAN_ALWAYS_ON_OFLOADS \
+       (NETIF_F_SG | NETIF_F_HW_CSUM | \
+        NETIF_F_GSO_ROBUST | NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ENCAP_ALL)
+
+#define IPVLAN_ALWAYS_ON \
+       (IPVLAN_ALWAYS_ON_OFLOADS | NETIF_F_LLTX | NETIF_F_VLAN_CHALLENGED)
+
 #define IPVLAN_FEATURES \
-       (NETIF_F_SG | NETIF_F_CSUM_MASK | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
+       (NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
         NETIF_F_GSO | NETIF_F_ALL_TSO | NETIF_F_GSO_ROBUST | \
         NETIF_F_GRO | NETIF_F_RXCSUM | \
         NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
 
+       /* NETIF_F_GSO_ENCAP_ALL NETIF_F_GSO_SOFTWARE Newly added */
+
 #define IPVLAN_STATE_MASK \
        ((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
 
@@ -125,7 +134,9 @@ static int ipvlan_init(struct net_device *dev)
        dev->state = (dev->state & ~IPVLAN_STATE_MASK) |
                     (phy_dev->state & IPVLAN_STATE_MASK);
        dev->features = phy_dev->features & IPVLAN_FEATURES;
-       dev->features |= NETIF_F_LLTX | NETIF_F_VLAN_CHALLENGED;
+       dev->features |= IPVLAN_ALWAYS_ON;
+       dev->vlan_features = phy_dev->vlan_features & IPVLAN_FEATURES;
+       dev->vlan_features |= IPVLAN_ALWAYS_ON_OFLOADS;
        dev->hw_enc_features |= dev->features;
        dev->gso_max_size = phy_dev->gso_max_size;
        dev->gso_max_segs = phy_dev->gso_max_segs;
@@ -227,7 +238,14 @@ static netdev_features_t ipvlan_fix_features(struct net_device *dev,
 {
        struct ipvl_dev *ipvlan = netdev_priv(dev);
 
-       return features & (ipvlan->sfeatures | ~IPVLAN_FEATURES);
+       features |= NETIF_F_ALL_FOR_ALL;
+       features &= (ipvlan->sfeatures | ~IPVLAN_FEATURES);
+       features = netdev_increment_features(ipvlan->phy_dev->features,
+                                            features, features);
+       features |= IPVLAN_ALWAYS_ON;
+       features &= (IPVLAN_FEATURES | IPVLAN_ALWAYS_ON);
+
+       return features;
 }
 
 static void ipvlan_change_rx_flags(struct net_device *dev, int change)
@@ -734,10 +752,9 @@ static int ipvlan_device_event(struct notifier_block *unused,
 
        case NETDEV_FEAT_CHANGE:
                list_for_each_entry(ipvlan, &port->ipvlans, pnode) {
-                       ipvlan->dev->features = dev->features & IPVLAN_FEATURES;
                        ipvlan->dev->gso_max_size = dev->gso_max_size;
                        ipvlan->dev->gso_max_segs = dev->gso_max_segs;
-                       netdev_features_change(ipvlan->dev);
+                       netdev_update_features(ipvlan->dev);
                }
                break;
 
index 7bcee41..3ca4daf 100644 (file)
@@ -295,14 +295,13 @@ static int dlci_close(struct net_device *dev)
 {
        struct dlci_local       *dlp;
        struct frad_local       *flp;
-       int                     err;
 
        netif_stop_queue(dev);
 
        dlp = netdev_priv(dev);
 
        flp = netdev_priv(dlp->slave);
-       err = (*flp->deactivate)(dlp->slave, dev);
+       (*flp->deactivate)(dlp->slave, dev);
 
        return 0;
 }
index dfc1677..386ed2a 100644 (file)
@@ -230,6 +230,7 @@ static void hdlc_setup_dev(struct net_device *dev)
        dev->max_mtu             = HDLC_MAX_MTU;
        dev->type                = ARPHRD_RAWHDLC;
        dev->hard_header_len     = 16;
+       dev->needed_headroom     = 0;
        dev->addr_len            = 0;
        dev->header_ops          = &hdlc_null_ops;
 }
index f70336b..f52b9fe 100644 (file)
@@ -107,8 +107,14 @@ static netdev_tx_t x25_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        int result;
 
+       /* There should be a pseudo header of 1 byte added by upper layers.
+        * Check to make sure it is there before reading it.
+        */
+       if (skb->len < 1) {
+               kfree_skb(skb);
+               return NETDEV_TX_OK;
+       }
 
-       /* X.25 to LAPB */
        switch (skb->data[0]) {
        case X25_IFACE_DATA:    /* Data to be transmitted */
                skb_pull(skb, 1);
@@ -294,6 +300,15 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
                        return result;
 
                memcpy(&state(hdlc)->settings, &new_settings, size);
+
+               /* There's no header_ops so hard_header_len should be 0. */
+               dev->hard_header_len = 0;
+               /* When transmitting data:
+                * first we'll remove a pseudo header of 1 byte,
+                * then we'll prepend an LAPB header of at most 3 bytes.
+                */
+               dev->needed_headroom = 3 - 1;
+
                dev->type = ARPHRD_X25;
                call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
                netif_dormant_off(dev);
index 7948a2d..2ff0080 100644 (file)
@@ -150,17 +150,17 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data);
 void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam);
 void rtl8180_set_anaparam2(struct rtl8180_priv *priv, u32 anaparam2);
 
-static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr)
+static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, const u8 __iomem *addr)
 {
        return ioread8(addr);
 }
 
-static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, __le16 __iomem *addr)
+static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, const __le16 __iomem *addr)
 {
        return ioread16(addr);
 }
 
-static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, __le32 __iomem *addr)
+static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, const __le32 __iomem *addr)
 {
        return ioread32(addr);
 }
index 423f9b8..3185efe 100644 (file)
@@ -1205,7 +1205,7 @@ int intel_ntb_peer_spad_write(struct ntb_dev *ntb, int pidx, int sidx,
                               ndev->peer_reg->spad);
 }
 
-static u64 xeon_db_ioread(void __iomem *mmio)
+static u64 xeon_db_ioread(const void __iomem *mmio)
 {
        return (u64)ioread16(mmio);
 }
index 2bc5d83..dea9398 100644 (file)
@@ -91,7 +91,7 @@
 #define GEN3_DB_TOTAL_SHIFT            33
 #define GEN3_SPAD_COUNT                        16
 
-static inline u64 gen3_db_ioread(void __iomem *mmio)
+static inline u64 gen3_db_ioread(const void __iomem *mmio)
 {
        return ioread64(mmio);
 }
index d61fcd9..05e2335 100644 (file)
@@ -103,7 +103,7 @@ struct intel_ntb_dev;
 struct intel_ntb_reg {
        int (*poll_link)(struct intel_ntb_dev *ndev);
        int (*link_is_up)(struct intel_ntb_dev *ndev);
-       u64 (*db_ioread)(void __iomem *mmio);
+       u64 (*db_ioread)(const void __iomem *mmio);
        void (*db_iowrite)(u64 db_bits, void __iomem *mmio);
        unsigned long                   ntb_ctl;
        resource_size_t                 db_size;
index 412d21d..0ff610e 100644 (file)
@@ -1490,10 +1490,8 @@ static int btt_rw_page(struct block_device *bdev, sector_t sector,
 {
        struct btt *btt = bdev->bd_disk->private_data;
        int rc;
-       unsigned int len;
 
-       len = hpage_nr_pages(page) * PAGE_SIZE;
-       rc = btt_do_bvec(btt, NULL, page, len, 0, op, sector);
+       rc = btt_do_bvec(btt, NULL, page, thp_size(page), 0, op, sector);
        if (rc == 0)
                page_endio(page, op_is_write(op), 0);
 
index 94790e6..fab29b5 100644 (file)
@@ -238,11 +238,9 @@ static int pmem_rw_page(struct block_device *bdev, sector_t sector,
        blk_status_t rc;
 
        if (op_is_write(op))
-               rc = pmem_do_write(pmem, page, 0, sector,
-                                  hpage_nr_pages(page) * PAGE_SIZE);
+               rc = pmem_do_write(pmem, page, 0, sector, thp_size(page));
        else
-               rc = pmem_do_read(pmem, page, 0, sector,
-                                  hpage_nr_pages(page) * PAGE_SIZE);
+               rc = pmem_do_read(pmem, page, 0, sector, thp_size(page));
        /*
         * The ->rw_page interface is subtle and tricky.  The core
         * retries on any error, so we can only invoke page_endio() in
index 004b2ea..276e939 100644 (file)
@@ -510,12 +510,12 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
            last->period > s2.period &&
            last->period <= state->period)
                dev_warn(chip->dev,
-                        ".apply didn't pick the best available period (requested: %u, applied: %u, possible: %u)\n",
+                        ".apply didn't pick the best available period (requested: %llu, applied: %llu, possible: %llu)\n",
                         state->period, s2.period, last->period);
 
        if (state->enabled && state->period < s2.period)
                dev_warn(chip->dev,
-                        ".apply is supposed to round down period (requested: %u, applied: %u)\n",
+                        ".apply is supposed to round down period (requested: %llu, applied: %llu)\n",
                         state->period, s2.period);
 
        if (state->enabled &&
@@ -524,14 +524,14 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
            last->duty_cycle > s2.duty_cycle &&
            last->duty_cycle <= state->duty_cycle)
                dev_warn(chip->dev,
-                        ".apply didn't pick the best available duty cycle (requested: %u/%u, applied: %u/%u, possible: %u/%u)\n",
+                        ".apply didn't pick the best available duty cycle (requested: %llu/%llu, applied: %llu/%llu, possible: %llu/%llu)\n",
                         state->duty_cycle, state->period,
                         s2.duty_cycle, s2.period,
                         last->duty_cycle, last->period);
 
        if (state->enabled && state->duty_cycle < s2.duty_cycle)
                dev_warn(chip->dev,
-                        ".apply is supposed to round down duty_cycle (requested: %u/%u, applied: %u/%u)\n",
+                        ".apply is supposed to round down duty_cycle (requested: %llu/%llu, applied: %llu/%llu)\n",
                         state->duty_cycle, state->period,
                         s2.duty_cycle, s2.period);
 
@@ -558,7 +558,7 @@ static void pwm_apply_state_debug(struct pwm_device *pwm,
            (s1.enabled && s1.period != last->period) ||
            (s1.enabled && s1.duty_cycle != last->duty_cycle)) {
                dev_err(chip->dev,
-                       ".apply is not idempotent (ena=%d pol=%d %u/%u) -> (ena=%d pol=%d %u/%u)\n",
+                       ".apply is not idempotent (ena=%d pol=%d %llu/%llu) -> (ena=%d pol=%d %llu/%llu)\n",
                        s1.enabled, s1.polarity, s1.duty_cycle, s1.period,
                        last->enabled, last->polarity, last->duty_cycle,
                        last->period);
@@ -1284,8 +1284,8 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
                if (state.enabled)
                        seq_puts(s, " enabled");
 
-               seq_printf(s, " period: %u ns", state.period);
-               seq_printf(s, " duty: %u ns", state.duty_cycle);
+               seq_printf(s, " period: %llu ns", state.period);
+               seq_printf(s, " duty: %llu ns", state.duty_cycle);
                seq_printf(s, " polarity: %s",
                           state.polarity ? "inverse" : "normal");
 
index 1f829ed..79b1e58 100644 (file)
@@ -85,8 +85,6 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        u64 tmp, multi, rate;
        u32 value, prescale;
 
-       rate = clk_get_rate(ip->clk);
-
        value = readl(ip->base + IPROC_PWM_CTRL_OFFSET);
 
        if (value & BIT(IPROC_PWM_CTRL_EN_SHIFT(pwm->hwpwm)))
@@ -99,6 +97,13 @@ static void iproc_pwmc_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        else
                state->polarity = PWM_POLARITY_INVERSED;
 
+       rate = clk_get_rate(ip->clk);
+       if (rate == 0) {
+               state->period = 0;
+               state->duty_cycle = 0;
+               return;
+       }
+
        value = readl(ip->base + IPROC_PWM_PRESCALE_OFFSET);
        prescale = value >> IPROC_PWM_PRESCALE_SHIFT(pwm->hwpwm);
        prescale &= IPROC_PWM_PRESCALE_MAX;
@@ -143,8 +148,7 @@ static int iproc_pwmc_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                value = rate * state->duty_cycle;
                duty = div64_u64(value, div);
 
-               if (period < IPROC_PWM_PERIOD_MIN ||
-                   duty < IPROC_PWM_DUTY_CYCLE_MIN)
+               if (period < IPROC_PWM_PERIOD_MIN)
                        return -EINVAL;
 
                if (period <= IPROC_PWM_PERIOD_MAX &&
index 81da91d..16c5898 100644 (file)
@@ -138,7 +138,7 @@ static int kona_pwmc_config(struct pwm_chip *chip, struct pwm_device *pwm,
                dc = div64_u64(val, div);
 
                /* If duty_ns or period_ns are not achievable then return */
-               if (pc < PERIOD_COUNT_MIN || dc < DUTY_CYCLE_HIGH_MIN)
+               if (pc < PERIOD_COUNT_MIN)
                        return -EINVAL;
 
                /* If pc and dc are in bounds, the calculation is done */
index 924d39a..ba9500a 100644 (file)
@@ -43,7 +43,7 @@ static void clps711x_pwm_update_val(struct clps711x_chip *priv, u32 n, u32 v)
 static unsigned int clps711x_get_duty(struct pwm_device *pwm, unsigned int v)
 {
        /* Duty cycle 0..15 max */
-       return DIV_ROUND_CLOSEST(v * 0xf, pwm->args.period);
+       return DIV64_U64_ROUND_CLOSEST(v * 0xf, pwm->args.period);
 }
 
 static int clps711x_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
index 5f3d7f7..fcdf6be 100644 (file)
@@ -124,7 +124,7 @@ static int pwm_imx_tpm_round_state(struct pwm_chip *chip,
                real_state->duty_cycle = state->duty_cycle;
 
        tmp = (u64)p->mod * real_state->duty_cycle;
-       p->val = DIV_ROUND_CLOSEST_ULL(tmp, real_state->period);
+       p->val = DIV64_U64_ROUND_CLOSEST(tmp, real_state->period);
 
        real_state->polarity = state->polarity;
        real_state->enabled = state->enabled;
index 732a6f3..c50d453 100644 (file)
@@ -202,7 +202,7 @@ static void pwm_imx27_wait_fifo_slot(struct pwm_chip *chip,
        sr = readl(imx->mmio_base + MX3_PWMSR);
        fifoav = FIELD_GET(MX3_PWMSR_FIFOAV, sr);
        if (fifoav == MX3_PWMSR_FIFOAV_4WORDS) {
-               period_ms = DIV_ROUND_UP(pwm_get_period(pwm),
+               period_ms = DIV_ROUND_UP_ULL(pwm_get_period(pwm),
                                         NSEC_PER_MSEC);
                msleep(period_ms);
 
index 674f0e2..7d33e36 100644 (file)
 #include <linux/regmap.h>
 #include <linux/slab.h>
 
-#define IQS620_PWR_SETTINGS                    0xD2
+#define IQS620_PWR_SETTINGS                    0xd2
 #define IQS620_PWR_SETTINGS_PWM_OUT            BIT(7)
 
-#define IQS620_PWM_DUTY_CYCLE                  0xD8
+#define IQS620_PWM_DUTY_CYCLE                  0xd8
 
 #define IQS620_PWM_PERIOD_NS                   1000000
 
@@ -46,7 +46,8 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 {
        struct iqs620_pwm_private *iqs620_pwm;
        struct iqs62x_core *iqs62x;
-       int duty_scale, ret;
+       u64 duty_scale;
+       int ret;
 
        if (state->polarity != PWM_POLARITY_NORMAL)
                return -ENOTSUPP;
@@ -69,7 +70,7 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
         * For lower duty cycles (e.g. 0), the PWM output is simply disabled to
         * allow an external pull-down resistor to hold the GPIO3/LTX pin low.
         */
-       duty_scale = state->duty_cycle * 256 / IQS620_PWM_PERIOD_NS;
+       duty_scale = div_u64(state->duty_cycle * 256, IQS620_PWM_PERIOD_NS);
 
        mutex_lock(&iqs620_pwm->lock);
 
@@ -81,7 +82,7 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        }
 
        if (duty_scale) {
-               u8 duty_val = min(duty_scale - 1, 0xFF);
+               u8 duty_val = min_t(u64, duty_scale - 1, 0xff);
 
                ret = regmap_write(iqs62x->regmap, IQS620_PWM_DUTY_CYCLE,
                                   duty_val);
@@ -93,7 +94,7 @@ static int iqs620_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 
        if (state->enabled && duty_scale) {
                ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
-                                        IQS620_PWR_SETTINGS_PWM_OUT, 0xFF);
+                                        IQS620_PWR_SETTINGS_PWM_OUT, 0xff);
                if (ret)
                        goto err_mutex;
        }
@@ -159,7 +160,7 @@ static int iqs620_pwm_notifier(struct notifier_block *notifier,
 
        ret = regmap_update_bits(iqs62x->regmap, IQS620_PWR_SETTINGS,
                                 IQS620_PWR_SETTINGS_PWM_OUT,
-                                iqs620_pwm->out_en ? 0xFF : 0);
+                                iqs620_pwm->out_en ? 0xff : 0);
 
 err_mutex:
        mutex_unlock(&iqs620_pwm->lock);
index b94e0d0..ab001ce 100644 (file)
@@ -46,6 +46,7 @@ struct pwm_mediatek_of_data {
  * @clk_main: the clock used by PWM core
  * @clk_pwms: the clock used by each PWM channel
  * @clk_freq: the fix clock frequency of legacy MIPS SoC
+ * @soc: pointer to chip's platform data
  */
 struct pwm_mediatek_chip {
        struct pwm_chip chip;
index 0d31833..358db4f 100644 (file)
@@ -14,7 +14,7 @@
  *   with a timer counter that goes up. When it overflows it gets
  *   reloaded with the load value and the pwm output goes up.
  *   When counter matches with match register, the output goes down.
- *   Reference Manual: http://www.ti.com/lit/ug/spruh73q/spruh73q.pdf
+ *   Reference Manual: https://www.ti.com/lit/ug/spruh73q/spruh73q.pdf
  *
  * Limitations:
  * - When PWM is stopped, timer counter gets stopped immediately. This
@@ -58,7 +58,7 @@
  * @mutex:             Mutex to protect pwm apply state
  * @dm_timer:          Pointer to omap dm timer.
  * @pdata:             Pointer to omap dm timer ops.
- * dm_timer_pdev:      Pointer to omap dm timer platform device
+ * @dm_timer_pdev:     Pointer to omap dm timer platform device
  */
 struct pwm_omap_dmtimer_chip {
        struct pwm_chip chip;
index cc63f9b..62de0bb 100644 (file)
@@ -181,7 +181,7 @@ static int pwm_sifive_apply(struct pwm_chip *chip, struct pwm_device *pwm,
         * consecutively
         */
        num = (u64)duty_cycle * (1U << PWM_SIFIVE_CMPWIDTH);
-       frac = DIV_ROUND_CLOSEST_ULL(num, state->period);
+       frac = DIV64_U64_ROUND_CLOSEST(num, state->period);
        /* The hardware cannot generate a 100% duty cycle */
        frac = min(frac, (1U << PWM_SIFIVE_CMPWIDTH) - 1);
 
index 67fca62..134c146 100644 (file)
@@ -61,7 +61,7 @@ static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        do_div(div, NSEC_PER_SEC);
        if (!div) {
                /* Clock is too slow to achieve requested period. */
-               dev_dbg(priv->chip.dev, "Can't reach %u ns\n",  state->period);
+               dev_dbg(priv->chip.dev, "Can't reach %llu ns\n", state->period);
                return -EINVAL;
        }
 
index 18fbbe3..961c59c 100644 (file)
@@ -285,7 +285,7 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        val = (duty & PWM_DTY_MASK) | PWM_PRD(period);
        sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
        sun4i_pwm->next_period[pwm->hwpwm] = jiffies +
-               usecs_to_jiffies(cstate.period / 1000 + 1);
+               nsecs_to_jiffies(cstate.period + 1000);
 
        if (state->polarity != PWM_POLARITY_NORMAL)
                ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
index ab38c82..683804c 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * ECAP PWM driver
  *
- * Copyright (C) 2012 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2012 Texas Instruments, Inc. - https://www.ti.com/
  */
 
 #include <linux/module.h>
index 7b4c770..0846917 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * EHRPWM PWM driver
  *
- * Copyright (C) 2012 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2012 Texas Instruments, Inc. - https://www.ti.com/
  */
 
 #include <linux/module.h>
index 2389b86..449dbc0 100644 (file)
@@ -42,7 +42,7 @@ static ssize_t period_show(struct device *child,
 
        pwm_get_state(pwm, &state);
 
-       return sprintf(buf, "%u\n", state.period);
+       return sprintf(buf, "%llu\n", state.period);
 }
 
 static ssize_t period_store(struct device *child,
@@ -52,10 +52,10 @@ static ssize_t period_store(struct device *child,
        struct pwm_export *export = child_to_pwm_export(child);
        struct pwm_device *pwm = export->pwm;
        struct pwm_state state;
-       unsigned int val;
+       u64 val;
        int ret;
 
-       ret = kstrtouint(buf, 0, &val);
+       ret = kstrtou64(buf, 0, &val);
        if (ret)
                return ret;
 
@@ -77,7 +77,7 @@ static ssize_t duty_cycle_show(struct device *child,
 
        pwm_get_state(pwm, &state);
 
-       return sprintf(buf, "%u\n", state.duty_cycle);
+       return sprintf(buf, "%llu\n", state.duty_cycle);
 }
 
 static ssize_t duty_cycle_store(struct device *child,
index 85c7959..1409c76 100644 (file)
@@ -256,9 +256,9 @@ static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new)
                WARN_ON(!fcf_dev);
                new->fcf_dev = NULL;
                fcoe_fcf_device_delete(fcf_dev);
-               kfree(new);
                mutex_unlock(&cdev->lock);
        }
+       kfree(new);
 }
 
 /**
index 19721db..d8cbc9c 100644 (file)
@@ -581,8 +581,12 @@ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
 
        if (PTR_ERR(fp) == -FC_EX_CLOSED)
                goto out;
-       if (IS_ERR(fp))
-               goto redisc;
+       if (IS_ERR(fp)) {
+               mutex_lock(&disc->disc_mutex);
+               fc_disc_restart(disc);
+               mutex_unlock(&disc->disc_mutex);
+               goto out;
+       }
 
        cp = fc_frame_payload_get(fp, sizeof(*cp));
        if (!cp)
@@ -609,7 +613,7 @@ static void fc_disc_gpn_id_resp(struct fc_seq *sp, struct fc_frame *fp,
                                new_rdata->disc_id = disc->disc_id;
                                fc_rport_login(new_rdata);
                        }
-                       goto out;
+                       goto free_fp;
                }
                rdata->disc_id = disc->disc_id;
                mutex_unlock(&rdata->rp_mutex);
@@ -626,6 +630,8 @@ redisc:
                fc_disc_restart(disc);
                mutex_unlock(&disc->disc_mutex);
        }
+free_fp:
+       fc_frame_free(fp);
 out:
        kref_put(&rdata->kref, fc_rport_destroy);
        if (!IS_ERR(fp))
index a62c60c..ece6c25 100644 (file)
@@ -6679,9 +6679,15 @@ lpfc_get_host_speed(struct Scsi_Host *shost)
                }
        } else if (lpfc_is_link_up(phba) && (phba->hba_flag & HBA_FCOE_MODE)) {
                switch (phba->fc_linkspeed) {
+               case LPFC_ASYNC_LINK_SPEED_1GBPS:
+                       fc_host_speed(shost) = FC_PORTSPEED_1GBIT;
+                       break;
                case LPFC_ASYNC_LINK_SPEED_10GBPS:
                        fc_host_speed(shost) = FC_PORTSPEED_10GBIT;
                        break;
+               case LPFC_ASYNC_LINK_SPEED_20GBPS:
+                       fc_host_speed(shost) = FC_PORTSPEED_20GBIT;
+                       break;
                case LPFC_ASYNC_LINK_SPEED_25GBPS:
                        fc_host_speed(shost) = FC_PORTSPEED_25GBIT;
                        break;
@@ -7406,12 +7412,26 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
 void
 lpfc_nvme_mod_param_dep(struct lpfc_hba *phba)
 {
-       if (phba->cfg_hdw_queue > phba->sli4_hba.num_present_cpu)
+       int  logit = 0;
+
+       if (phba->cfg_hdw_queue > phba->sli4_hba.num_present_cpu) {
                phba->cfg_hdw_queue = phba->sli4_hba.num_present_cpu;
-       if (phba->cfg_irq_chann > phba->sli4_hba.num_present_cpu)
+               logit = 1;
+       }
+       if (phba->cfg_irq_chann > phba->sli4_hba.num_present_cpu) {
                phba->cfg_irq_chann = phba->sli4_hba.num_present_cpu;
-       if (phba->cfg_irq_chann > phba->cfg_hdw_queue)
+               logit = 1;
+       }
+       if (phba->cfg_irq_chann > phba->cfg_hdw_queue) {
                phba->cfg_irq_chann = phba->cfg_hdw_queue;
+               logit = 1;
+       }
+       if (logit)
+               lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+                               "2006 Reducing Queues - CPU limitation: "
+                               "IRQ %d HDWQ %d\n",
+                               phba->cfg_irq_chann,
+                               phba->cfg_hdw_queue);
 
        if (phba->cfg_enable_fc4_type & LPFC_ENABLE_NVME &&
            phba->nvmet_support) {
index 1d88fed..6f9d648 100644 (file)
@@ -2494,13 +2494,12 @@ lpfc_sli4_bsg_link_diag_test(struct bsg_job *job)
        diag_status_reply = (struct diag_status *)
                            bsg_reply->reply_data.vendor_reply.vendor_rsp;
 
-       if (job->reply_len <
-           sizeof(struct fc_bsg_request) + sizeof(struct diag_status)) {
+       if (job->reply_len < sizeof(*bsg_reply) + sizeof(*diag_status_reply)) {
                lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
                                "3012 Received Run link diag test reply "
                                "below minimum size (%d): reply_len:%d\n",
-                               (int)(sizeof(struct fc_bsg_request) +
-                               sizeof(struct diag_status)),
+                               (int)(sizeof(*bsg_reply) +
+                               sizeof(*diag_status_reply)),
                                job->reply_len);
                rc = -EINVAL;
                goto job_error;
@@ -3418,8 +3417,7 @@ lpfc_bsg_get_dfc_rev(struct bsg_job *job)
        event_reply = (struct get_mgmt_rev_reply *)
                bsg_reply->reply_data.vendor_reply.vendor_rsp;
 
-       if (job->reply_len <
-           sizeof(struct fc_bsg_request) + sizeof(struct get_mgmt_rev_reply)) {
+       if (job->reply_len < sizeof(*bsg_reply) + sizeof(*event_reply)) {
                lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
                                "2741 Received GET_DFC_REV reply below "
                                "minimum size\n");
@@ -5202,8 +5200,8 @@ lpfc_menlo_cmd(struct bsg_job *job)
                goto no_dd_data;
        }
 
-       if (job->reply_len <
-           sizeof(struct fc_bsg_request) + sizeof(struct menlo_response)) {
+       if (job->reply_len < sizeof(*bsg_reply) +
+                               sizeof(struct menlo_response)) {
                lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
                                "2785 Received MENLO_CMD reply below "
                                "minimum size\n");
@@ -5359,9 +5357,7 @@ lpfc_forced_link_speed(struct bsg_job *job)
        forced_reply = (struct forced_link_speed_support_reply *)
                bsg_reply->reply_data.vendor_reply.vendor_rsp;
 
-       if (job->reply_len <
-           sizeof(struct fc_bsg_request) +
-           sizeof(struct forced_link_speed_support_reply)) {
+       if (job->reply_len < sizeof(*bsg_reply) + sizeof(*forced_reply)) {
                lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
                                "0049 Received FORCED_LINK_SPEED reply below "
                                "minimum size\n");
@@ -5715,8 +5711,7 @@ lpfc_get_trunk_info(struct bsg_job *job)
        event_reply = (struct lpfc_trunk_info *)
                bsg_reply->reply_data.vendor_reply.vendor_rsp;
 
-       if (job->reply_len <
-           sizeof(struct fc_bsg_request) + sizeof(struct lpfc_trunk_info)) {
+       if (job->reply_len < sizeof(*bsg_reply) + sizeof(*event_reply)) {
                lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
                                "2728 Received GET TRUNK _INFO reply below "
                                "minimum size\n");
index dd9f2bf..ef2015f 100644 (file)
@@ -713,7 +713,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                /* This is a GID_FT completing so the gidft_inp counter was
                 * incremented before the GID_FT was issued to the wire.
                 */
-               vport->gidft_inp--;
+               if (vport->gidft_inp)
+                       vport->gidft_inp--;
 
                /*
                 * Skip processing the NS response
@@ -741,11 +742,14 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                goto out;
 
                        /* CT command is being retried */
-                       vport->gidft_inp--;
                        rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
                                         vport->fc_ns_retry, type);
                        if (rc == 0)
                                goto out;
+                       else { /* Unable to send NS cmd */
+                               if (vport->gidft_inp)
+                                       vport->gidft_inp--;
+                       }
                }
                if (vport->fc_flag & FC_RSCN_MODE)
                        lpfc_els_flush_rscn(vport);
@@ -825,7 +829,8 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                (uint32_t) CTrsp->ReasonCode,
                                (uint32_t) CTrsp->Explanation);
                }
-               vport->gidft_inp--;
+               if (vport->gidft_inp)
+                       vport->gidft_inp--;
        }
 
        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
@@ -918,7 +923,8 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                /* This is a GID_PT completing so the gidft_inp counter was
                 * incremented before the GID_PT was issued to the wire.
                 */
-               vport->gidft_inp--;
+               if (vport->gidft_inp)
+                       vport->gidft_inp--;
 
                /*
                 * Skip processing the NS response
@@ -942,11 +948,14 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                vport->fc_ns_retry++;
 
                        /* CT command is being retried */
-                       vport->gidft_inp--;
                        rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_PT,
                                         vport->fc_ns_retry, GID_PT_N_PORT);
                        if (rc == 0)
                                goto out;
+                       else { /* Unable to send NS cmd */
+                               if (vport->gidft_inp)
+                                       vport->gidft_inp--;
+                       }
                }
                if (vport->fc_flag & FC_RSCN_MODE)
                        lpfc_els_flush_rscn(vport);
@@ -1027,7 +1036,8 @@ lpfc_cmpl_ct_cmd_gid_pt(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                                (uint32_t)CTrsp->ReasonCode,
                                (uint32_t)CTrsp->Explanation);
                }
-               vport->gidft_inp--;
+               if (vport->gidft_inp)
+                       vport->gidft_inp--;
        }
 
        lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
index 85d4e40..48dc63f 100644 (file)
@@ -3937,10 +3937,14 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
                case LSRJT_UNABLE_TPC:
                        /* The driver has a VALID PLOGI but the rport has
                         * rejected the PRLI - can't do it now.  Delay
-                        * for 1 second and try again - don't care about
-                        * the explanation.
+                        * for 1 second and try again.
+                        *
+                        * However, if explanation is REQ_UNSUPPORTED there's
+                        * no point to retry PRLI.
                         */
-                       if (cmd == ELS_CMD_PRLI || cmd == ELS_CMD_NVMEPRLI) {
+                       if ((cmd == ELS_CMD_PRLI || cmd == ELS_CMD_NVMEPRLI) &&
+                           stat.un.b.lsRjtRsnCodeExp !=
+                           LSEXP_REQ_UNSUPPORTED) {
                                delay = 1000;
                                maxretry = lpfc_max_els_tries + 1;
                                retry = 1;
index c4a7e82..c697259 100644 (file)
@@ -4577,6 +4577,13 @@ static void lpfc_host_supported_speeds_set(struct Scsi_Host *shost)
        struct lpfc_hba   *phba = vport->phba;
 
        fc_host_supported_speeds(shost) = 0;
+       /*
+        * Avoid reporting supported link speed for FCoE as it can't be
+        * controlled via FCoE.
+        */
+       if (phba->hba_flag & HBA_FCOE_MODE)
+               return;
+
        if (phba->lmt & LMT_128Gb)
                fc_host_supported_speeds(shost) |= FC_PORTSPEED_128GBIT;
        if (phba->lmt & LMT_64Gb)
@@ -4910,6 +4917,9 @@ lpfc_sli4_port_speed_parse(struct lpfc_hba *phba, uint32_t evt_code,
                case LPFC_ASYNC_LINK_SPEED_40GBPS:
                        port_speed = 40000;
                        break;
+               case LPFC_ASYNC_LINK_SPEED_100GBPS:
+                       port_speed = 100000;
+                       break;
                default:
                        port_speed = 0;
                }
@@ -8589,7 +8599,7 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
                                "VPI(B:%d M:%d) "
                                "VFI(B:%d M:%d) "
                                "RPI(B:%d M:%d) "
-                               "FCFI:%d EQ:%d CQ:%d WQ:%d RQ:%d\n",
+                               "FCFI:%d EQ:%d CQ:%d WQ:%d RQ:%d lmt:x%x\n",
                                phba->sli4_hba.extents_in_use,
                                phba->sli4_hba.max_cfg_param.xri_base,
                                phba->sli4_hba.max_cfg_param.max_xri,
@@ -8603,7 +8613,8 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
                                phba->sli4_hba.max_cfg_param.max_eq,
                                phba->sli4_hba.max_cfg_param.max_cq,
                                phba->sli4_hba.max_cfg_param.max_wq,
-                               phba->sli4_hba.max_cfg_param.max_rq);
+                               phba->sli4_hba.max_cfg_param.max_rq,
+                               phba->lmt);
 
                /*
                 * Calculate queue resources based on how
@@ -8626,7 +8637,8 @@ lpfc_sli4_read_config(struct lpfc_hba *phba)
                if ((phba->cfg_irq_chann > qmin) ||
                    (phba->cfg_hdw_queue > qmin)) {
                        lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
-                                       "2005 Reducing Queues: "
+                                       "2005 Reducing Queues - "
+                                       "FW resource limitation: "
                                        "WQ %d CQ %d EQ %d: min %d: "
                                        "IRQ %d HDWQ %d\n",
                                        phba->sli4_hba.max_cfg_param.max_wq,
@@ -14100,17 +14112,18 @@ lpfc_init(void)
                printk(KERN_ERR "Could not register lpfcmgmt device, "
                        "misc_register returned with status %d", error);
 
+       error = -ENOMEM;
        lpfc_transport_functions.vport_create = lpfc_vport_create;
        lpfc_transport_functions.vport_delete = lpfc_vport_delete;
        lpfc_transport_template =
                                fc_attach_transport(&lpfc_transport_functions);
        if (lpfc_transport_template == NULL)
-               return -ENOMEM;
+               goto unregister;
        lpfc_vport_transport_template =
                fc_attach_transport(&lpfc_vport_transport_functions);
        if (lpfc_vport_transport_template == NULL) {
                fc_release_transport(lpfc_transport_template);
-               return -ENOMEM;
+               goto unregister;
        }
        lpfc_nvme_cmd_template();
        lpfc_nvmet_cmd_template();
@@ -14136,6 +14149,8 @@ unwind:
 cpuhp_failure:
        fc_release_transport(lpfc_transport_template);
        fc_release_transport(lpfc_vport_transport_template);
+unregister:
+       misc_deregister(&lpfc_mgmt_dev);
 
        return error;
 }
index e4c710f..cad53d1 100644 (file)
@@ -1745,7 +1745,13 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
                }
        }
 
-       if (ndlp->nlp_type & NLP_FCP_TARGET) {
+       if (ndlp->nlp_type & NLP_FCP_TARGET)
+               ndlp->nlp_fc4_type |= NLP_FC4_FCP;
+
+       if (ndlp->nlp_type & NLP_NVME_TARGET)
+               ndlp->nlp_fc4_type |= NLP_FC4_NVME;
+
+       if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) {
                ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
                lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
        } else {
index a4430ae..d4ade7c 100644 (file)
@@ -2110,7 +2110,7 @@ lpfc_nvmet_destroy_targetport(struct lpfc_hba *phba)
                }
                tgtp->tport_unreg_cmp = &tport_unreg_cmp;
                nvmet_fc_unregister_targetport(phba->targetport);
-               if (!wait_for_completion_timeout(tgtp->tport_unreg_cmp,
+               if (!wait_for_completion_timeout(&tport_unreg_cmp,
                                        msecs_to_jiffies(LPFC_NVMET_WAIT_TMO)))
                        lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
                                        "6179 Unreg targetport x%px timeout "
index 8582b51..4cd7ded 100644 (file)
@@ -13650,7 +13650,11 @@ lpfc_sli4_sp_handle_rcqe(struct lpfc_hba *phba, struct lpfc_rcqe *rcqe)
                    fc_hdr->fh_r_ctl == FC_RCTL_DD_UNSOL_DATA) {
                        spin_unlock_irqrestore(&phba->hbalock, iflags);
                        /* Handle MDS Loopback frames */
-                       lpfc_sli4_handle_mds_loopback(phba->pport, dma_buf);
+                       if  (!(phba->pport->load_flag & FC_UNLOADING))
+                               lpfc_sli4_handle_mds_loopback(phba->pport,
+                                                             dma_buf);
+                       else
+                               lpfc_in_buf_free(phba, &dma_buf->dbuf);
                        break;
                }
 
@@ -18363,7 +18367,10 @@ lpfc_sli4_handle_received_buffer(struct lpfc_hba *phba,
            fc_hdr->fh_r_ctl == FC_RCTL_DD_UNSOL_DATA) {
                vport = phba->pport;
                /* Handle MDS Loopback frames */
-               lpfc_sli4_handle_mds_loopback(vport, dmabuf);
+               if  (!(phba->pport->load_flag & FC_UNLOADING))
+                       lpfc_sli4_handle_mds_loopback(vport, dmabuf);
+               else
+                       lpfc_in_buf_free(phba, &dmabuf->dbuf);
                return;
        }
 
index 1987c66..20adec4 100644 (file)
@@ -20,7 +20,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "12.8.0.2"
+#define LPFC_DRIVER_VERSION "12.8.0.3"
 #define LPFC_DRIVER_NAME               "lpfc"
 
 /* Used for SLI 2/3 */
index e443dee..c9abed8 100644 (file)
@@ -1526,7 +1526,7 @@ int sas_rphy_add(struct sas_rphy *rphy)
        list_add_tail(&rphy->list, &sas_host->rphy_list);
        if (identify->device_type == SAS_END_DEVICE &&
            (identify->target_port_protocols &
-            (SAS_PROTOCOL_SSP|SAS_PROTOCOL_STP|SAS_PROTOCOL_SATA)))
+            (SAS_PROTOCOL_SSP | SAS_PROTOCOL_STP | SAS_PROTOCOL_SATA)))
                rphy->scsi_target_id = sas_host->next_target_id++;
        else if (identify->device_type == SAS_END_DEVICE)
                rphy->scsi_target_id = -1;
index acde0ca..95018e6 100644 (file)
@@ -2578,8 +2578,6 @@ sd_print_capacity(struct scsi_disk *sdkp,
                sd_printk(KERN_NOTICE, sdkp,
                          "%u-byte physical blocks\n",
                          sdkp->physical_block_size);
-
-       sd_zbc_print_zones(sdkp);
 }
 
 /* called with buffer of length 512 */
@@ -3220,6 +3218,14 @@ static int sd_revalidate_disk(struct gendisk *disk)
        sd_config_write_same(sdkp);
        kfree(buffer);
 
+       /*
+        * For a zoned drive, revalidating the zones can be done only once
+        * the gendisk capacity is set. So if this fails, set back the gendisk
+        * capacity to 0.
+        */
+       if (sd_zbc_revalidate_zones(sdkp))
+               set_capacity_revalidate_and_notify(disk, 0, false);
+
  out:
        return 0;
 }
index 27c0f4e..4933e7d 100644 (file)
@@ -75,7 +75,9 @@ struct scsi_disk {
        struct opal_dev *opal_dev;
 #ifdef CONFIG_BLK_DEV_ZONED
        u32             nr_zones;
+       u32             rev_nr_zones;
        u32             zone_blocks;
+       u32             rev_zone_blocks;
        u32             zones_optimal_open;
        u32             zones_optimal_nonseq;
        u32             zones_max_open;
@@ -215,8 +217,8 @@ static inline int sd_is_zoned(struct scsi_disk *sdkp)
 
 int sd_zbc_init_disk(struct scsi_disk *sdkp);
 void sd_zbc_release_disk(struct scsi_disk *sdkp);
-extern int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer);
-extern void sd_zbc_print_zones(struct scsi_disk *sdkp);
+int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer);
+int sd_zbc_revalidate_zones(struct scsi_disk *sdkp);
 blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd,
                                         unsigned char op, bool all);
 unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes,
@@ -242,7 +244,10 @@ static inline int sd_zbc_read_zones(struct scsi_disk *sdkp,
        return 0;
 }
 
-static inline void sd_zbc_print_zones(struct scsi_disk *sdkp) {}
+static inline int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)
+{
+       return 0;
+}
 
 static inline blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd,
                                                       unsigned char op,
index 4717e79..0e94ff0 100644 (file)
@@ -634,6 +634,23 @@ static int sd_zbc_check_capacity(struct scsi_disk *sdkp, unsigned char *buf,
        return 0;
 }
 
+static void sd_zbc_print_zones(struct scsi_disk *sdkp)
+{
+       if (!sd_is_zoned(sdkp) || !sdkp->capacity)
+               return;
+
+       if (sdkp->capacity & (sdkp->zone_blocks - 1))
+               sd_printk(KERN_NOTICE, sdkp,
+                         "%u zones of %u logical blocks + 1 runt zone\n",
+                         sdkp->nr_zones - 1,
+                         sdkp->zone_blocks);
+       else
+               sd_printk(KERN_NOTICE, sdkp,
+                         "%u zones of %u logical blocks\n",
+                         sdkp->nr_zones,
+                         sdkp->zone_blocks);
+}
+
 static void sd_zbc_revalidate_zones_cb(struct gendisk *disk)
 {
        struct scsi_disk *sdkp = scsi_disk(disk);
@@ -641,36 +658,31 @@ static void sd_zbc_revalidate_zones_cb(struct gendisk *disk)
        swap(sdkp->zones_wp_offset, sdkp->rev_wp_offset);
 }
 
-static int sd_zbc_revalidate_zones(struct scsi_disk *sdkp,
-                                  u32 zone_blocks,
-                                  unsigned int nr_zones)
+int sd_zbc_revalidate_zones(struct scsi_disk *sdkp)
 {
        struct gendisk *disk = sdkp->disk;
+       struct request_queue *q = disk->queue;
+       u32 zone_blocks = sdkp->rev_zone_blocks;
+       unsigned int nr_zones = sdkp->rev_nr_zones;
+       u32 max_append;
        int ret = 0;
 
+       if (!sd_is_zoned(sdkp))
+               return 0;
+
        /*
         * Make sure revalidate zones are serialized to ensure exclusive
         * updates of the scsi disk data.
         */
        mutex_lock(&sdkp->rev_mutex);
 
-       /*
-        * Revalidate the disk zones to update the device request queue zone
-        * bitmaps and the zone write pointer offset array. Do this only once
-        * the device capacity is set on the second revalidate execution for
-        * disk scan or if something changed when executing a normal revalidate.
-        */
-       if (sdkp->first_scan) {
-               sdkp->zone_blocks = zone_blocks;
-               sdkp->nr_zones = nr_zones;
-               goto unlock;
-       }
-
        if (sdkp->zone_blocks == zone_blocks &&
            sdkp->nr_zones == nr_zones &&
            disk->queue->nr_zones == nr_zones)
                goto unlock;
 
+       sdkp->zone_blocks = zone_blocks;
+       sdkp->nr_zones = nr_zones;
        sdkp->rev_wp_offset = kvcalloc(nr_zones, sizeof(u32), GFP_NOIO);
        if (!sdkp->rev_wp_offset) {
                ret = -ENOMEM;
@@ -682,6 +694,21 @@ static int sd_zbc_revalidate_zones(struct scsi_disk *sdkp,
        kvfree(sdkp->rev_wp_offset);
        sdkp->rev_wp_offset = NULL;
 
+       if (ret) {
+               sdkp->zone_blocks = 0;
+               sdkp->nr_zones = 0;
+               sdkp->capacity = 0;
+               goto unlock;
+       }
+
+       max_append = min_t(u32, logical_to_sectors(sdkp->device, zone_blocks),
+                          q->limits.max_segments << (PAGE_SHIFT - 9));
+       max_append = min_t(u32, max_append, queue_max_hw_sectors(q));
+
+       blk_queue_max_zone_append_sectors(q, max_append);
+
+       sd_zbc_print_zones(sdkp);
+
 unlock:
        mutex_unlock(&sdkp->rev_mutex);
 
@@ -694,7 +721,6 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)
        struct request_queue *q = disk->queue;
        unsigned int nr_zones;
        u32 zone_blocks = 0;
-       u32 max_append;
        int ret;
 
        if (!sd_is_zoned(sdkp))
@@ -728,22 +754,8 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buf)
        sdkp->device->use_16_for_rw = 1;
        sdkp->device->use_10_for_rw = 0;
 
-       ret = sd_zbc_revalidate_zones(sdkp, zone_blocks, nr_zones);
-       if (ret)
-               goto err;
-
-       /*
-        * On the first scan 'chunk_sectors' isn't setup yet, so calling
-        * blk_queue_max_zone_append_sectors() will result in a WARN(). Defer
-        * this setting to the second scan.
-        */
-       if (sdkp->first_scan)
-               return 0;
-
-       max_append = min_t(u32, logical_to_sectors(sdkp->device, zone_blocks),
-                          q->limits.max_segments << (PAGE_SHIFT - 9));
-
-       blk_queue_max_zone_append_sectors(q, max_append);
+       sdkp->rev_nr_zones = nr_zones;
+       sdkp->rev_zone_blocks = zone_blocks;
 
        return 0;
 
@@ -753,23 +765,6 @@ err:
        return ret;
 }
 
-void sd_zbc_print_zones(struct scsi_disk *sdkp)
-{
-       if (!sd_is_zoned(sdkp) || !sdkp->capacity)
-               return;
-
-       if (sdkp->capacity & (sdkp->zone_blocks - 1))
-               sd_printk(KERN_NOTICE, sdkp,
-                         "%u zones of %u logical blocks + 1 runt zone\n",
-                         sdkp->nr_zones - 1,
-                         sdkp->zone_blocks);
-       else
-               sd_printk(KERN_NOTICE, sdkp,
-                         "%u zones of %u logical blocks\n",
-                         sdkp->nr_zones,
-                         sdkp->zone_blocks);
-}
-
 int sd_zbc_init_disk(struct scsi_disk *sdkp)
 {
        if (!sd_is_zoned(sdkp))
index eeb028b..fd72d90 100644 (file)
@@ -36,21 +36,6 @@ static void sh_clk_write(int value, struct clk *clk)
                iowrite32(value, clk->mapped_reg);
 }
 
-static unsigned int r8(const void __iomem *addr)
-{
-       return ioread8(addr);
-}
-
-static unsigned int r16(const void __iomem *addr)
-{
-       return ioread16(addr);
-}
-
-static unsigned int r32(const void __iomem *addr)
-{
-       return ioread32(addr);
-}
-
 static int sh_clk_mstp_enable(struct clk *clk)
 {
        sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk);
@@ -61,11 +46,11 @@ static int sh_clk_mstp_enable(struct clk *clk)
                        (phys_addr_t)clk->enable_reg + clk->mapped_reg;
 
                if (clk->flags & CLK_ENABLE_REG_8BIT)
-                       read = r8;
+                       read = ioread8;
                else if (clk->flags & CLK_ENABLE_REG_16BIT)
-                       read = r16;
+                       read = ioread16;
                else
-                       read = r32;
+                       read = ioread32;
 
                for (i = 1000;
                     (read(mapped_status) & (1 << clk->enable_bit)) && i;
index c3008e4..c6ea760 100644 (file)
@@ -1017,4 +1017,7 @@ config SPI_SLAVE_SYSTEM_CONTROL
 
 endif # SPI_SLAVE
 
+config SPI_DYNAMIC
+       def_bool ACPI || OF_DYNAMIC || SPI_SLAVE
+
 endif # SPI
index 4c643df..d4b33b3 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of_platform.h>
+#include <linux/pinctrl/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/reset.h>
 #include <linux/spi/spi.h>
@@ -441,7 +442,8 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
 {
        u32 div, mbrdiv;
 
-       div = DIV_ROUND_UP(spi->clk_rate, speed_hz);
+       /* Ensure spi->clk_rate is even */
+       div = DIV_ROUND_UP(spi->clk_rate & ~0x1, speed_hz);
 
        /*
         * SPI framework set xfer->speed_hz to master->max_speed_hz if
@@ -467,20 +469,27 @@ static int stm32_spi_prepare_mbr(struct stm32_spi *spi, u32 speed_hz,
 /**
  * stm32h7_spi_prepare_fthlv - Determine FIFO threshold level
  * @spi: pointer to the spi controller data structure
+ * @xfer_len: length of the message to be transferred
  */
-static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi)
+static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi, u32 xfer_len)
 {
-       u32 fthlv, half_fifo;
+       u32 fthlv, half_fifo, packet;
 
        /* data packet should not exceed 1/2 of fifo space */
        half_fifo = (spi->fifo_size / 2);
 
+       /* data_packet should not exceed transfer length */
+       if (half_fifo > xfer_len)
+               packet = xfer_len;
+       else
+               packet = half_fifo;
+
        if (spi->cur_bpw <= 8)
-               fthlv = half_fifo;
+               fthlv = packet;
        else if (spi->cur_bpw <= 16)
-               fthlv = half_fifo / 2;
+               fthlv = packet / 2;
        else
-               fthlv = half_fifo / 4;
+               fthlv = packet / 4;
 
        /* align packet size with data registers access */
        if (spi->cur_bpw > 8)
@@ -488,6 +497,9 @@ static u32 stm32h7_spi_prepare_fthlv(struct stm32_spi *spi)
        else
                fthlv -= (fthlv % 4); /* multiple of 4 */
 
+       if (!fthlv)
+               fthlv = 1;
+
        return fthlv;
 }
 
@@ -966,13 +978,13 @@ static irqreturn_t stm32h7_spi_irq_thread(int irq, void *dev_id)
                if (!spi->cur_usedma && (spi->rx_buf && (spi->rx_len > 0)))
                        stm32h7_spi_read_rxfifo(spi, false);
 
-       writel_relaxed(mask, spi->base + STM32H7_SPI_IFCR);
+       writel_relaxed(sr & mask, spi->base + STM32H7_SPI_IFCR);
 
        spin_unlock_irqrestore(&spi->lock, flags);
 
        if (end) {
-               spi_finalize_current_transfer(master);
                stm32h7_spi_disable(spi);
+               spi_finalize_current_transfer(master);
        }
 
        return IRQ_HANDLED;
@@ -1393,7 +1405,7 @@ static void stm32h7_spi_set_bpw(struct stm32_spi *spi)
        cfg1_setb |= (bpw << STM32H7_SPI_CFG1_DSIZE_SHIFT) &
                     STM32H7_SPI_CFG1_DSIZE;
 
-       spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi);
+       spi->cur_fthlv = stm32h7_spi_prepare_fthlv(spi, spi->cur_xferlen);
        fthlv = spi->cur_fthlv - 1;
 
        cfg1_clrb |= STM32H7_SPI_CFG1_FTHLV;
@@ -1585,39 +1597,33 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
        unsigned long flags;
        unsigned int comm_type;
        int nb_words, ret = 0;
+       int mbr;
 
        spin_lock_irqsave(&spi->lock, flags);
 
-       if (spi->cur_bpw != transfer->bits_per_word) {
-               spi->cur_bpw = transfer->bits_per_word;
-               spi->cfg->set_bpw(spi);
-       }
-
-       if (spi->cur_speed != transfer->speed_hz) {
-               int mbr;
+       spi->cur_xferlen = transfer->len;
 
-               /* Update spi->cur_speed with real clock speed */
-               mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz,
-                                           spi->cfg->baud_rate_div_min,
-                                           spi->cfg->baud_rate_div_max);
-               if (mbr < 0) {
-                       ret = mbr;
-                       goto out;
-               }
+       spi->cur_bpw = transfer->bits_per_word;
+       spi->cfg->set_bpw(spi);
 
-               transfer->speed_hz = spi->cur_speed;
-               stm32_spi_set_mbr(spi, mbr);
+       /* Update spi->cur_speed with real clock speed */
+       mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz,
+                                   spi->cfg->baud_rate_div_min,
+                                   spi->cfg->baud_rate_div_max);
+       if (mbr < 0) {
+               ret = mbr;
+               goto out;
        }
 
+       transfer->speed_hz = spi->cur_speed;
+       stm32_spi_set_mbr(spi, mbr);
+
        comm_type = stm32_spi_communication_type(spi_dev, transfer);
-       if (spi->cur_comm != comm_type) {
-               ret = spi->cfg->set_mode(spi, comm_type);
+       ret = spi->cfg->set_mode(spi, comm_type);
+       if (ret < 0)
+               goto out;
 
-               if (ret < 0)
-                       goto out;
-
-               spi->cur_comm = comm_type;
-       }
+       spi->cur_comm = comm_type;
 
        if (spi->cfg->set_data_idleness)
                spi->cfg->set_data_idleness(spi, transfer->len);
@@ -1635,8 +1641,6 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
                        goto out;
        }
 
-       spi->cur_xferlen = transfer->len;
-
        dev_dbg(spi->dev, "transfer communication mode set to %d\n",
                spi->cur_comm);
        dev_dbg(spi->dev,
@@ -1996,6 +2000,8 @@ static int stm32_spi_remove(struct platform_device *pdev)
 
        pm_runtime_disable(&pdev->dev);
 
+       pinctrl_pm_select_sleep_state(&pdev->dev);
+
        return 0;
 }
 
@@ -2007,13 +2013,18 @@ static int stm32_spi_runtime_suspend(struct device *dev)
 
        clk_disable_unprepare(spi->clk);
 
-       return 0;
+       return pinctrl_pm_select_sleep_state(dev);
 }
 
 static int stm32_spi_runtime_resume(struct device *dev)
 {
        struct spi_master *master = dev_get_drvdata(dev);
        struct stm32_spi *spi = spi_master_get_devdata(master);
+       int ret;
+
+       ret = pinctrl_pm_select_default_state(dev);
+       if (ret)
+               return ret;
 
        return clk_prepare_enable(spi->clk);
 }
@@ -2043,10 +2054,23 @@ static int stm32_spi_resume(struct device *dev)
                return ret;
 
        ret = spi_master_resume(master);
-       if (ret)
+       if (ret) {
                clk_disable_unprepare(spi->clk);
+               return ret;
+       }
 
-       return ret;
+       ret = pm_runtime_get_sync(dev);
+       if (ret) {
+               dev_err(dev, "Unable to power device:%d\n", ret);
+               return ret;
+       }
+
+       spi->cfg->config(spi);
+
+       pm_runtime_mark_last_busy(dev);
+       pm_runtime_put_autosuspend(dev);
+
+       return 0;
 }
 #endif
 
index 6626587..dc12af0 100644 (file)
@@ -475,6 +475,12 @@ static LIST_HEAD(spi_controller_list);
  */
 static DEFINE_MUTEX(board_lock);
 
+/*
+ * Prevents addition of devices with same chip select and
+ * addition of devices below an unregistering controller.
+ */
+static DEFINE_MUTEX(spi_add_lock);
+
 /**
  * spi_alloc_device - Allocate a new SPI device
  * @ctlr: Controller to which device is connected
@@ -554,7 +560,6 @@ static int spi_dev_check(struct device *dev, void *data)
  */
 int spi_add_device(struct spi_device *spi)
 {
-       static DEFINE_MUTEX(spi_add_lock);
        struct spi_controller *ctlr = spi->controller;
        struct device *dev = ctlr->dev.parent;
        int status;
@@ -582,6 +587,13 @@ int spi_add_device(struct spi_device *spi)
                goto done;
        }
 
+       /* Controller may unregister concurrently */
+       if (IS_ENABLED(CONFIG_SPI_DYNAMIC) &&
+           !device_is_registered(&ctlr->dev)) {
+               status = -ENODEV;
+               goto done;
+       }
+
        /* Descriptors take precedence */
        if (ctlr->cs_gpiods)
                spi->cs_gpiod = ctlr->cs_gpiods[spi->chip_select];
@@ -2795,6 +2807,10 @@ void spi_unregister_controller(struct spi_controller *ctlr)
        struct spi_controller *found;
        int id = ctlr->bus_num;
 
+       /* Prevent addition of new devices, unregister existing ones */
+       if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
+               mutex_lock(&spi_add_lock);
+
        device_for_each_child(&ctlr->dev, NULL, __unregister);
 
        /* First make sure that this controller was ever added */
@@ -2815,6 +2831,9 @@ void spi_unregister_controller(struct spi_controller *ctlr)
        if (found == ctlr)
                idr_remove(&spi_master_idr, id);
        mutex_unlock(&board_lock);
+
+       if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
+               mutex_unlock(&spi_add_lock);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_controller);
 
index 0369405..27c85f2 100644 (file)
@@ -31,7 +31,7 @@ void iscsit_put_transport(struct iscsit_transport *t)
        module_put(t->owner);
 }
 
-int iscsit_register_transport(struct iscsit_transport *t)
+void iscsit_register_transport(struct iscsit_transport *t)
 {
        INIT_LIST_HEAD(&t->t_node);
 
@@ -40,8 +40,6 @@ int iscsit_register_transport(struct iscsit_transport *t)
        mutex_unlock(&transport_mutex);
 
        pr_debug("Registered iSCSI transport: %s\n", t->name);
-
-       return 0;
 }
 EXPORT_SYMBOL(iscsit_register_transport);
 
index a2e710d..b668224 100644 (file)
@@ -499,4 +499,15 @@ config SPRD_THERMAL
        help
          Support for the Spreadtrum thermal sensor driver in the Linux thermal
          framework.
+
+config KHADAS_MCU_FAN_THERMAL
+       tristate "Khadas MCU controller FAN cooling support"
+       depends on OF || COMPILE_TEST
+       depends on MFD_KHADAS_MCU
+       select MFD_CORE
+       select REGMAP
+       help
+         If you say yes here you get support for the FAN controlled
+         by the Microcontroller found on the Khadas VIM boards.
+
 endif
index b8d96d2..b64dd50 100644 (file)
@@ -61,3 +61,4 @@ obj-$(CONFIG_ZX2967_THERMAL)  += zx2967_thermal.o
 obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
 obj-$(CONFIG_AMLOGIC_THERMAL)     += amlogic_thermal.o
 obj-$(CONFIG_SPRD_THERMAL)     += sprd_thermal.o
+obj-$(CONFIG_KHADAS_MCU_FAN_THERMAL)   += khadas_mcu_fan.o
diff --git a/drivers/thermal/khadas_mcu_fan.c b/drivers/thermal/khadas_mcu_fan.c
new file mode 100644 (file)
index 0000000..9eadd2d
--- /dev/null
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Khadas MCU Controlled FAN driver
+ *
+ * Copyright (C) 2020 BayLibre SAS
+ * Author(s): Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/khadas-mcu.h>
+#include <linux/regmap.h>
+#include <linux/sysfs.h>
+#include <linux/thermal.h>
+
+#define MAX_LEVEL 3
+
+struct khadas_mcu_fan_ctx {
+       struct khadas_mcu *mcu;
+       unsigned int level;
+       struct thermal_cooling_device *cdev;
+};
+
+static int khadas_mcu_fan_set_level(struct khadas_mcu_fan_ctx *ctx,
+                                   unsigned int level)
+{
+       int ret;
+
+       ret = regmap_write(ctx->mcu->regmap, KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
+                          level);
+       if (ret)
+               return ret;
+
+       ctx->level = level;
+
+       return 0;
+}
+
+static int khadas_mcu_fan_get_max_state(struct thermal_cooling_device *cdev,
+                                       unsigned long *state)
+{
+       *state = MAX_LEVEL;
+
+       return 0;
+}
+
+static int khadas_mcu_fan_get_cur_state(struct thermal_cooling_device *cdev,
+                                       unsigned long *state)
+{
+       struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
+
+       *state = ctx->level;
+
+       return 0;
+}
+
+static int
+khadas_mcu_fan_set_cur_state(struct thermal_cooling_device *cdev,
+                            unsigned long state)
+{
+       struct khadas_mcu_fan_ctx *ctx = cdev->devdata;
+
+       if (state > MAX_LEVEL)
+               return -EINVAL;
+
+       if (state == ctx->level)
+               return 0;
+
+       return khadas_mcu_fan_set_level(ctx, state);
+}
+
+static const struct thermal_cooling_device_ops khadas_mcu_fan_cooling_ops = {
+       .get_max_state = khadas_mcu_fan_get_max_state,
+       .get_cur_state = khadas_mcu_fan_get_cur_state,
+       .set_cur_state = khadas_mcu_fan_set_cur_state,
+};
+
+static int khadas_mcu_fan_probe(struct platform_device *pdev)
+{
+       struct khadas_mcu *mcu = dev_get_drvdata(pdev->dev.parent);
+       struct thermal_cooling_device *cdev;
+       struct device *dev = &pdev->dev;
+       struct khadas_mcu_fan_ctx *ctx;
+       int ret;
+
+       ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+       ctx->mcu = mcu;
+       platform_set_drvdata(pdev, ctx);
+
+       cdev = devm_thermal_of_cooling_device_register(dev->parent,
+                       dev->parent->of_node, "khadas-mcu-fan", ctx,
+                       &khadas_mcu_fan_cooling_ops);
+       if (IS_ERR(cdev)) {
+               ret = PTR_ERR(cdev);
+               dev_err(dev, "Failed to register khadas-mcu-fan as cooling device: %d\n",
+                       ret);
+               return ret;
+       }
+       ctx->cdev = cdev;
+       thermal_cdev_update(cdev);
+
+       return 0;
+}
+
+static void khadas_mcu_fan_shutdown(struct platform_device *pdev)
+{
+       struct khadas_mcu_fan_ctx *ctx = platform_get_drvdata(pdev);
+
+       khadas_mcu_fan_set_level(ctx, 0);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int khadas_mcu_fan_suspend(struct device *dev)
+{
+       struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev);
+       unsigned int level_save = ctx->level;
+       int ret;
+
+       ret = khadas_mcu_fan_set_level(ctx, 0);
+       if (ret)
+               return ret;
+
+       ctx->level = level_save;
+
+       return 0;
+}
+
+static int khadas_mcu_fan_resume(struct device *dev)
+{
+       struct khadas_mcu_fan_ctx *ctx = dev_get_drvdata(dev);
+
+       return khadas_mcu_fan_set_level(ctx, ctx->level);
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(khadas_mcu_fan_pm, khadas_mcu_fan_suspend,
+                        khadas_mcu_fan_resume);
+
+static const struct platform_device_id khadas_mcu_fan_id_table[] = {
+       { .name = "khadas-mcu-fan-ctrl", },
+       {},
+};
+MODULE_DEVICE_TABLE(platform, khadas_mcu_fan_id_table);
+
+static struct platform_driver khadas_mcu_fan_driver = {
+       .probe          = khadas_mcu_fan_probe,
+       .shutdown       = khadas_mcu_fan_shutdown,
+       .driver = {
+               .name           = "khadas-mcu-fan-ctrl",
+               .pm             = &khadas_mcu_fan_pm,
+       },
+       .id_table       = khadas_mcu_fan_id_table,
+};
+
+module_platform_driver(khadas_mcu_fan_driver);
+
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_DESCRIPTION("Khadas MCU FAN driver");
+MODULE_LICENSE("GPL");
index 86a02af..61ca8ab 100644 (file)
 
 struct vfio_pci_ioeventfd {
        struct list_head        next;
+       struct vfio_pci_device  *vdev;
        struct virqfd           *virqfd;
        void __iomem            *addr;
        uint64_t                data;
        loff_t                  pos;
        int                     bar;
        int                     count;
+       bool                    test_mem;
 };
 
 struct vfio_pci_irq_ctx {
index 916b184..9e353c4 100644 (file)
 #define vfio_ioread8   ioread8
 #define vfio_iowrite8  iowrite8
 
+#define VFIO_IOWRITE(size) \
+static int vfio_pci_iowrite##size(struct vfio_pci_device *vdev,                \
+                       bool test_mem, u##size val, void __iomem *io)   \
+{                                                                      \
+       if (test_mem) {                                                 \
+               down_read(&vdev->memory_lock);                          \
+               if (!__vfio_pci_memory_enabled(vdev)) {                 \
+                       up_read(&vdev->memory_lock);                    \
+                       return -EIO;                                    \
+               }                                                       \
+       }                                                               \
+                                                                       \
+       vfio_iowrite##size(val, io);                                    \
+                                                                       \
+       if (test_mem)                                                   \
+               up_read(&vdev->memory_lock);                            \
+                                                                       \
+       return 0;                                                       \
+}
+
+VFIO_IOWRITE(8)
+VFIO_IOWRITE(16)
+VFIO_IOWRITE(32)
+#ifdef iowrite64
+VFIO_IOWRITE(64)
+#endif
+
+#define VFIO_IOREAD(size) \
+static int vfio_pci_ioread##size(struct vfio_pci_device *vdev,         \
+                       bool test_mem, u##size *val, void __iomem *io)  \
+{                                                                      \
+       if (test_mem) {                                                 \
+               down_read(&vdev->memory_lock);                          \
+               if (!__vfio_pci_memory_enabled(vdev)) {                 \
+                       up_read(&vdev->memory_lock);                    \
+                       return -EIO;                                    \
+               }                                                       \
+       }                                                               \
+                                                                       \
+       *val = vfio_ioread##size(io);                                   \
+                                                                       \
+       if (test_mem)                                                   \
+               up_read(&vdev->memory_lock);                            \
+                                                                       \
+       return 0;                                                       \
+}
+
+VFIO_IOREAD(8)
+VFIO_IOREAD(16)
+VFIO_IOREAD(32)
+
 /*
  * Read or write from an __iomem region (MMIO or I/O port) with an excluded
  * range which is inaccessible.  The excluded range drops writes and fills
  * reads with -1.  This is intended for handling MSI-X vector tables and
  * leftover space for ROM BARs.
  */
-static ssize_t do_io_rw(void __iomem *io, char __user *buf,
+static ssize_t do_io_rw(struct vfio_pci_device *vdev, bool test_mem,
+                       void __iomem *io, char __user *buf,
                        loff_t off, size_t count, size_t x_start,
                        size_t x_end, bool iswrite)
 {
        ssize_t done = 0;
+       int ret;
 
        while (count) {
                size_t fillable, filled;
@@ -66,9 +119,15 @@ static ssize_t do_io_rw(void __iomem *io, char __user *buf,
                                if (copy_from_user(&val, buf, 4))
                                        return -EFAULT;
 
-                               vfio_iowrite32(val, io + off);
+                               ret = vfio_pci_iowrite32(vdev, test_mem,
+                                                        val, io + off);
+                               if (ret)
+                                       return ret;
                        } else {
-                               val = vfio_ioread32(io + off);
+                               ret = vfio_pci_ioread32(vdev, test_mem,
+                                                       &val, io + off);
+                               if (ret)
+                                       return ret;
 
                                if (copy_to_user(buf, &val, 4))
                                        return -EFAULT;
@@ -82,9 +141,15 @@ static ssize_t do_io_rw(void __iomem *io, char __user *buf,
                                if (copy_from_user(&val, buf, 2))
                                        return -EFAULT;
 
-                               vfio_iowrite16(val, io + off);
+                               ret = vfio_pci_iowrite16(vdev, test_mem,
+                                                        val, io + off);
+                               if (ret)
+                                       return ret;
                        } else {
-                               val = vfio_ioread16(io + off);
+                               ret = vfio_pci_ioread16(vdev, test_mem,
+                                                       &val, io + off);
+                               if (ret)
+                                       return ret;
 
                                if (copy_to_user(buf, &val, 2))
                                        return -EFAULT;
@@ -98,9 +163,15 @@ static ssize_t do_io_rw(void __iomem *io, char __user *buf,
                                if (copy_from_user(&val, buf, 1))
                                        return -EFAULT;
 
-                               vfio_iowrite8(val, io + off);
+                               ret = vfio_pci_iowrite8(vdev, test_mem,
+                                                       val, io + off);
+                               if (ret)
+                                       return ret;
                        } else {
-                               val = vfio_ioread8(io + off);
+                               ret = vfio_pci_ioread8(vdev, test_mem,
+                                                      &val, io + off);
+                               if (ret)
+                                       return ret;
 
                                if (copy_to_user(buf, &val, 1))
                                        return -EFAULT;
@@ -178,14 +249,6 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
 
        count = min(count, (size_t)(end - pos));
 
-       if (res->flags & IORESOURCE_MEM) {
-               down_read(&vdev->memory_lock);
-               if (!__vfio_pci_memory_enabled(vdev)) {
-                       up_read(&vdev->memory_lock);
-                       return -EIO;
-               }
-       }
-
        if (bar == PCI_ROM_RESOURCE) {
                /*
                 * The ROM can fill less space than the BAR, so we start the
@@ -213,7 +276,8 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
                x_end = vdev->msix_offset + vdev->msix_size;
        }
 
-       done = do_io_rw(io, buf, pos, count, x_start, x_end, iswrite);
+       done = do_io_rw(vdev, res->flags & IORESOURCE_MEM, io, buf, pos,
+                       count, x_start, x_end, iswrite);
 
        if (done >= 0)
                *ppos += done;
@@ -221,9 +285,6 @@ ssize_t vfio_pci_bar_rw(struct vfio_pci_device *vdev, char __user *buf,
        if (bar == PCI_ROM_RESOURCE)
                pci_unmap_rom(pdev, io);
 out:
-       if (res->flags & IORESOURCE_MEM)
-               up_read(&vdev->memory_lock);
-
        return done;
 }
 
@@ -278,7 +339,12 @@ ssize_t vfio_pci_vga_rw(struct vfio_pci_device *vdev, char __user *buf,
                return ret;
        }
 
-       done = do_io_rw(iomem, buf, off, count, 0, 0, iswrite);
+       /*
+        * VGA MMIO is a legacy, non-BAR resource that hopefully allows
+        * probing, so we don't currently worry about access in relation
+        * to the memory enable bit in the command register.
+        */
+       done = do_io_rw(vdev, false, iomem, buf, off, count, 0, 0, iswrite);
 
        vga_put(vdev->pdev, rsrc);
 
@@ -296,17 +362,21 @@ static int vfio_pci_ioeventfd_handler(void *opaque, void *unused)
 
        switch (ioeventfd->count) {
        case 1:
-               vfio_iowrite8(ioeventfd->data, ioeventfd->addr);
+               vfio_pci_iowrite8(ioeventfd->vdev, ioeventfd->test_mem,
+                                 ioeventfd->data, ioeventfd->addr);
                break;
        case 2:
-               vfio_iowrite16(ioeventfd->data, ioeventfd->addr);
+               vfio_pci_iowrite16(ioeventfd->vdev, ioeventfd->test_mem,
+                                  ioeventfd->data, ioeventfd->addr);
                break;
        case 4:
-               vfio_iowrite32(ioeventfd->data, ioeventfd->addr);
+               vfio_pci_iowrite32(ioeventfd->vdev, ioeventfd->test_mem,
+                                  ioeventfd->data, ioeventfd->addr);
                break;
 #ifdef iowrite64
        case 8:
-               vfio_iowrite64(ioeventfd->data, ioeventfd->addr);
+               vfio_pci_iowrite64(ioeventfd->vdev, ioeventfd->test_mem,
+                                  ioeventfd->data, ioeventfd->addr);
                break;
 #endif
        }
@@ -378,11 +448,13 @@ long vfio_pci_ioeventfd(struct vfio_pci_device *vdev, loff_t offset,
                goto out_unlock;
        }
 
+       ioeventfd->vdev = vdev;
        ioeventfd->addr = vdev->barmap[bar] + pos;
        ioeventfd->data = data;
        ioeventfd->pos = pos;
        ioeventfd->bar = bar;
        ioeventfd->count = count;
+       ioeventfd->test_mem = vdev->pdev->resource[bar].flags & IORESOURCE_MEM;
 
        ret = vfio_virqfd_enable(ioeventfd, vfio_pci_ioeventfd_handler,
                                 NULL, NULL, &ioeventfd->virqfd, fd);
index 6990fc7..c992973 100644 (file)
@@ -1424,13 +1424,16 @@ static int vfio_bus_type(struct device *dev, void *data)
 static int vfio_iommu_replay(struct vfio_iommu *iommu,
                             struct vfio_domain *domain)
 {
-       struct vfio_domain *d;
+       struct vfio_domain *d = NULL;
        struct rb_node *n;
        unsigned long limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
        int ret;
 
        /* Arbitrarily pick the first domain in the list for lookups */
-       d = list_first_entry(&iommu->domain_list, struct vfio_domain, next);
+       if (!list_empty(&iommu->domain_list))
+               d = list_first_entry(&iommu->domain_list,
+                                    struct vfio_domain, next);
+
        n = rb_first(&iommu->dma_list);
 
        for (; n; n = rb_next(n)) {
@@ -1448,6 +1451,11 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
                                phys_addr_t p;
                                dma_addr_t i;
 
+                               if (WARN_ON(!d)) { /* mapped w/o a domain?! */
+                                       ret = -EINVAL;
+                                       goto unwind;
+                               }
+
                                phys = iommu_iova_to_phys(d->domain, iova);
 
                                if (WARN_ON(!phys)) {
@@ -1477,7 +1485,7 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
                                if (npage <= 0) {
                                        WARN_ON(!npage);
                                        ret = (int)npage;
-                                       return ret;
+                                       goto unwind;
                                }
 
                                phys = pfn << PAGE_SHIFT;
@@ -1486,14 +1494,67 @@ static int vfio_iommu_replay(struct vfio_iommu *iommu,
 
                        ret = iommu_map(domain->domain, iova, phys,
                                        size, dma->prot | domain->prot);
-                       if (ret)
-                               return ret;
+                       if (ret) {
+                               if (!dma->iommu_mapped)
+                                       vfio_unpin_pages_remote(dma, iova,
+                                                       phys >> PAGE_SHIFT,
+                                                       size >> PAGE_SHIFT,
+                                                       true);
+                               goto unwind;
+                       }
 
                        iova += size;
                }
+       }
+
+       /* All dmas are now mapped, defer to second tree walk for unwind */
+       for (n = rb_first(&iommu->dma_list); n; n = rb_next(n)) {
+               struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node);
+
                dma->iommu_mapped = true;
        }
+
        return 0;
+
+unwind:
+       for (; n; n = rb_prev(n)) {
+               struct vfio_dma *dma = rb_entry(n, struct vfio_dma, node);
+               dma_addr_t iova;
+
+               if (dma->iommu_mapped) {
+                       iommu_unmap(domain->domain, dma->iova, dma->size);
+                       continue;
+               }
+
+               iova = dma->iova;
+               while (iova < dma->iova + dma->size) {
+                       phys_addr_t phys, p;
+                       size_t size;
+                       dma_addr_t i;
+
+                       phys = iommu_iova_to_phys(domain->domain, iova);
+                       if (!phys) {
+                               iova += PAGE_SIZE;
+                               continue;
+                       }
+
+                       size = PAGE_SIZE;
+                       p = phys + size;
+                       i = iova + size;
+                       while (i < dma->iova + dma->size &&
+                              p == iommu_iova_to_phys(domain->domain, i)) {
+                               size += PAGE_SIZE;
+                               p += PAGE_SIZE;
+                               i += PAGE_SIZE;
+                       }
+
+                       iommu_unmap(domain->domain, iova, size);
+                       vfio_unpin_pages_remote(dma, iova, phys >> PAGE_SHIFT,
+                                               size >> PAGE_SHIFT, true);
+               }
+       }
+
+       return ret;
 }
 
 /*
index eff64db..dfc7608 100644 (file)
@@ -601,7 +601,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
                pb->scale = data->max_brightness;
        }
 
-       pb->lth_brightness = data->lth_brightness * (state.period / pb->scale);
+       pb->lth_brightness = data->lth_brightness * (div_u64(state.period,
+                               pb->scale));
 
        props.type = BACKLIGHT_RAW;
        props.max_brightness = data->max_brightness;
index 8e06ba9..09425ec 100644 (file)
@@ -312,7 +312,7 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
                /* Enable the PWM */
                pwm_enable(par->pwm);
 
-               dev_dbg(&par->client->dev, "Using PWM%d with a %dns period.\n",
+               dev_dbg(&par->client->dev, "Using PWM%d with a %lluns period.\n",
                        par->pwm->pwm, pwm_get_period(par->pwm));
        }
 
index 9bdc6f6..3e14e70 100644 (file)
  * method, i.e. 32-bit accesses for 32-bit fields, 16-bit accesses
  * for 16-bit fields and 8-bit accesses for 8-bit fields.
  */
-static inline u8 vp_ioread8(u8 __iomem *addr)
+static inline u8 vp_ioread8(const u8 __iomem *addr)
 {
        return ioread8(addr);
 }
-static inline u16 vp_ioread16 (__le16 __iomem *addr)
+static inline u16 vp_ioread16 (const __le16 __iomem *addr)
 {
        return ioread16(addr);
 }
 
-static inline u32 vp_ioread32(__le32 __iomem *addr)
+static inline u32 vp_ioread32(const __le32 __iomem *addr)
 {
        return ioread32(addr);
 }
index 1d339ef..ea6c1e7 100644 (file)
@@ -52,9 +52,7 @@ config XEN_BALLOON_MEMORY_HOTPLUG
 
 config XEN_BALLOON_MEMORY_HOTPLUG_LIMIT
        int "Hotplugged memory limit (in GiB) for a PV guest"
-       default 512 if X86_64
-       default 4 if X86_32
-       range 0 64 if X86_32
+       default 512
        depends on XEN_HAVE_PVMMU
        depends on XEN_BALLOON_MEMORY_HOTPLUG
        help
index 75d3bb9..b1b6eeb 100644 (file)
@@ -613,6 +613,14 @@ dmabuf_imp_to_refs(struct gntdev_dmabuf_priv *priv, struct device *dev,
                goto fail_detach;
        }
 
+       /* Check that we have zero offset. */
+       if (sgt->sgl->offset) {
+               ret = ERR_PTR(-EINVAL);
+               pr_debug("DMA buffer has %d bytes offset, user-space expects 0\n",
+                        sgt->sgl->offset);
+               goto fail_unmap;
+       }
+
        /* Check number of pages that imported buffer has. */
        if (attach->dmabuf->size != gntdev_dmabuf->nr_pages << PAGE_SHIFT) {
                ret = ERR_PTR(-EINVAL);
index 15a99f9..39def02 100644 (file)
@@ -500,10 +500,9 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
        }
 
 #ifdef CONFIG_9P_FSCACHE
-       if (v9ses->fscache) {
+       if (v9ses->fscache)
                v9fs_cache_session_put_cookie(v9ses);
-               kfree(v9ses->cachetag);
-       }
+       kfree(v9ses->cachetag);
 #endif
        kfree(v9ses->uname);
        kfree(v9ses->aname);
index c9255d3..ae0c38a 100644 (file)
@@ -223,8 +223,7 @@ v9fs_blank_wstat(struct p9_wstat *wstat)
 struct inode *v9fs_alloc_inode(struct super_block *sb)
 {
        struct v9fs_inode *v9inode;
-       v9inode = (struct v9fs_inode *)kmem_cache_alloc(v9fs_inode_cache,
-                                                       GFP_KERNEL);
+       v9inode = kmem_cache_alloc(v9fs_inode_cache, GFP_KERNEL);
        if (!v9inode)
                return NULL;
 #ifdef CONFIG_9P_FSCACHE
@@ -368,59 +367,6 @@ struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
        return inode;
 }
 
-/*
-static struct v9fs_fid*
-v9fs_clone_walk(struct v9fs_session_info *v9ses, u32 fid, struct dentry *dentry)
-{
-       int err;
-       int nfid;
-       struct v9fs_fid *ret;
-       struct v9fs_fcall *fcall;
-
-       nfid = v9fs_get_idpool(&v9ses->fidpool);
-       if (nfid < 0) {
-               eprintk(KERN_WARNING, "no free fids available\n");
-               return ERR_PTR(-ENOSPC);
-       }
-
-       err = v9fs_t_walk(v9ses, fid, nfid, (char *) dentry->d_name.name,
-               &fcall);
-
-       if (err < 0) {
-               if (fcall && fcall->id == RWALK)
-                       goto clunk_fid;
-
-               PRINT_FCALL_ERROR("walk error", fcall);
-               v9fs_put_idpool(nfid, &v9ses->fidpool);
-               goto error;
-       }
-
-       kfree(fcall);
-       fcall = NULL;
-       ret = v9fs_fid_create(v9ses, nfid);
-       if (!ret) {
-               err = -ENOMEM;
-               goto clunk_fid;
-       }
-
-       err = v9fs_fid_insert(ret, dentry);
-       if (err < 0) {
-               v9fs_fid_destroy(ret);
-               goto clunk_fid;
-       }
-
-       return ret;
-
-clunk_fid:
-       v9fs_t_clunk(v9ses, nfid);
-
-error:
-       kfree(fcall);
-       return ERR_PTR(err);
-}
-*/
-
-
 /**
  * v9fs_clear_inode - release an inode
  * @inode: inode to release
@@ -1090,7 +1036,7 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
 {
        int retval;
        struct v9fs_session_info *v9ses;
-       struct p9_fid *fid;
+       struct p9_fid *fid = NULL;
        struct p9_wstat wstat;
 
        p9_debug(P9_DEBUG_VFS, "\n");
@@ -1100,7 +1046,12 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
 
        retval = -EPERM;
        v9ses = v9fs_dentry2v9ses(dentry);
-       fid = v9fs_fid_lookup(dentry);
+       if (iattr->ia_valid & ATTR_FILE) {
+               fid = iattr->ia_file->private_data;
+               WARN_ON(!fid);
+       }
+       if (!fid)
+               fid = v9fs_fid_lookup(dentry);
        if(IS_ERR(fid))
                return PTR_ERR(fid);
 
index 60328b2..0028ecc 100644 (file)
@@ -540,7 +540,7 @@ static int v9fs_mapped_iattr_valid(int iattr_valid)
 int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
 {
        int retval;
-       struct p9_fid *fid;
+       struct p9_fid *fid = NULL;
        struct p9_iattr_dotl p9attr;
        struct inode *inode = d_inode(dentry);
 
@@ -560,7 +560,12 @@ int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
        p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
        p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
 
-       fid = v9fs_fid_lookup(dentry);
+       if (iattr->ia_valid & ATTR_FILE) {
+               fid = iattr->ia_file->private_data;
+               WARN_ON(!fid);
+       }
+       if (!fid)
+               fid = v9fs_fid_lookup(dentry);
        if (IS_ERR(fid))
                return PTR_ERR(fid);
 
index 24fd163..97cab12 100644 (file)
@@ -235,6 +235,7 @@ int afs_put_operation(struct afs_operation *op)
        afs_end_cursor(&op->ac);
        afs_put_serverlist(op->net, op->server_list);
        afs_put_volume(op->net, op->volume, afs_volume_trace_put_put_op);
+       key_put(op->key);
        kfree(op);
        return ret;
 }
index f3a0f41..75105f4 100644 (file)
@@ -20,7 +20,7 @@
  * another mount. This situation arises when starting automount(8)
  * or other user space daemon which uses direct mounts or offset
  * mounts (used for autofs lazy mount/umount of nested mount trees),
- * which have been left busy at at service shutdown.
+ * which have been left busy at service shutdown.
  */
 
 typedef int (*ioctl_fn)(struct file *, struct autofs_sb_info *,
@@ -496,7 +496,7 @@ static int autofs_dev_ioctl_askumount(struct file *fp,
  * located path is the root of a mount we return 1 along with
  * the super magic of the mount or 0 otherwise.
  *
- * In both cases the the device number (as returned by
+ * In both cases the device number (as returned by
  * new_encode_dev()) is also returned.
  */
 static int autofs_dev_ioctl_ismountpoint(struct file *fp,
index 0ad1309..a275ee3 100644 (file)
@@ -4886,6 +4886,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol)
                full_path = build_unc_path_to_root(vol, cifs_sb, !!count);
                if (IS_ERR(full_path)) {
                        rc = PTR_ERR(full_path);
+                       full_path = NULL;
                        break;
                }
                /* Chase referral */
index b9db736..eba01d0 100644 (file)
@@ -115,6 +115,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
        vars->oparms.fid = &fid;
        vars->oparms.reconnect = false;
        vars->oparms.mode = mode;
+       vars->oparms.cifs_sb = cifs_sb;
 
        rqst[num_rqst].rq_iov = &vars->open_iov[0];
        rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE;
index 24c2ac3..667d70a 100644 (file)
@@ -3913,7 +3913,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
        case MID_RESPONSE_MALFORMED:
                credits.value = le16_to_cpu(shdr->CreditRequest);
                credits.instance = server->reconnect_instance;
-               /* fall through */
+               fallthrough;
        default:
                rdata->result = -EIO;
        }
@@ -4146,7 +4146,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
        case MID_RESPONSE_MALFORMED:
                credits.value = le16_to_cpu(rsp->sync_hdr.CreditRequest);
                credits.instance = server->reconnect_instance;
-               /* fall through */
+               fallthrough;
        default:
                wdata->result = -EIO;
                break;
index 2a3af95..dc506b7 100644 (file)
@@ -508,9 +508,9 @@ struct io_async_msghdr {
 
 struct io_async_rw {
        struct iovec                    fast_iov[UIO_FASTIOV];
-       struct iovec                    *iov;
-       ssize_t                         nr_segs;
-       ssize_t                         size;
+       const struct iovec              *free_iovec;
+       struct iov_iter                 iter;
+       size_t                          bytes_done;
        struct wait_page_queue          wpq;
 };
 
@@ -898,6 +898,7 @@ static void io_put_req(struct io_kiocb *req);
 static void io_double_put_req(struct io_kiocb *req);
 static void __io_double_put_req(struct io_kiocb *req);
 static struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req);
+static void __io_queue_linked_timeout(struct io_kiocb *req);
 static void io_queue_linked_timeout(struct io_kiocb *req);
 static int __io_sqe_files_update(struct io_ring_ctx *ctx,
                                 struct io_uring_files_update *ip,
@@ -914,9 +915,9 @@ static void io_file_put_work(struct work_struct *work);
 static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
                               struct iovec **iovec, struct iov_iter *iter,
                               bool needs_lock);
-static int io_setup_async_rw(struct io_kiocb *req, ssize_t io_size,
-                            struct iovec *iovec, struct iovec *fast_iov,
-                            struct iov_iter *iter);
+static int io_setup_async_rw(struct io_kiocb *req, const struct iovec *iovec,
+                            const struct iovec *fast_iov,
+                            struct iov_iter *iter, bool force);
 
 static struct kmem_cache *req_cachep;
 
@@ -1107,10 +1108,16 @@ static void __io_commit_cqring(struct io_ring_ctx *ctx)
        }
 }
 
-static void io_req_clean_work(struct io_kiocb *req)
+/*
+ * Returns true if we need to defer file table putting. This can only happen
+ * from the error path with REQ_F_COMP_LOCKED set.
+ */
+static bool io_req_clean_work(struct io_kiocb *req)
 {
        if (!(req->flags & REQ_F_WORK_INITIALIZED))
-               return;
+               return false;
+
+       req->flags &= ~REQ_F_WORK_INITIALIZED;
 
        if (req->work.mm) {
                mmdrop(req->work.mm);
@@ -1123,6 +1130,9 @@ static void io_req_clean_work(struct io_kiocb *req)
        if (req->work.fs) {
                struct fs_struct *fs = req->work.fs;
 
+               if (req->flags & REQ_F_COMP_LOCKED)
+                       return true;
+
                spin_lock(&req->work.fs->lock);
                if (--fs->users)
                        fs = NULL;
@@ -1131,7 +1141,8 @@ static void io_req_clean_work(struct io_kiocb *req)
                        free_fs_struct(fs);
                req->work.fs = NULL;
        }
-       req->flags &= ~REQ_F_WORK_INITIALIZED;
+
+       return false;
 }
 
 static void io_prep_async_work(struct io_kiocb *req)
@@ -1179,7 +1190,7 @@ static void io_prep_async_link(struct io_kiocb *req)
                        io_prep_async_work(cur);
 }
 
-static void __io_queue_async_work(struct io_kiocb *req)
+static struct io_kiocb *__io_queue_async_work(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
        struct io_kiocb *link = io_prep_linked_timeout(req);
@@ -1187,16 +1198,19 @@ static void __io_queue_async_work(struct io_kiocb *req)
        trace_io_uring_queue_async_work(ctx, io_wq_is_hashed(&req->work), req,
                                        &req->work, req->flags);
        io_wq_enqueue(ctx->io_wq, &req->work);
-
-       if (link)
-               io_queue_linked_timeout(link);
+       return link;
 }
 
 static void io_queue_async_work(struct io_kiocb *req)
 {
+       struct io_kiocb *link;
+
        /* init ->work of the whole link before punting */
        io_prep_async_link(req);
-       __io_queue_async_work(req);
+       link = __io_queue_async_work(req);
+
+       if (link)
+               io_queue_linked_timeout(link);
 }
 
 static void io_kill_timeout(struct io_kiocb *req)
@@ -1229,12 +1243,19 @@ static void __io_queue_deferred(struct io_ring_ctx *ctx)
        do {
                struct io_defer_entry *de = list_first_entry(&ctx->defer_list,
                                                struct io_defer_entry, list);
+               struct io_kiocb *link;
 
                if (req_need_defer(de->req, de->seq))
                        break;
                list_del_init(&de->list);
                /* punt-init is done before queueing for defer */
-               __io_queue_async_work(de->req);
+               link = __io_queue_async_work(de->req);
+               if (link) {
+                       __io_queue_linked_timeout(link);
+                       /* drop submission reference */
+                       link->flags |= REQ_F_COMP_LOCKED;
+                       io_put_req(link);
+               }
                kfree(de);
        } while (!list_empty(&ctx->defer_list));
 }
@@ -1533,7 +1554,7 @@ static inline void io_put_file(struct io_kiocb *req, struct file *file,
                fput(file);
 }
 
-static void io_dismantle_req(struct io_kiocb *req)
+static bool io_dismantle_req(struct io_kiocb *req)
 {
        io_clean_op(req);
 
@@ -1541,7 +1562,6 @@ static void io_dismantle_req(struct io_kiocb *req)
                kfree(req->io);
        if (req->file)
                io_put_file(req, req->file, (req->flags & REQ_F_FIXED_FILE));
-       io_req_clean_work(req);
 
        if (req->flags & REQ_F_INFLIGHT) {
                struct io_ring_ctx *ctx = req->ctx;
@@ -1553,15 +1573,15 @@ static void io_dismantle_req(struct io_kiocb *req)
                        wake_up(&ctx->inflight_wait);
                spin_unlock_irqrestore(&ctx->inflight_lock, flags);
        }
+
+       return io_req_clean_work(req);
 }
 
-static void __io_free_req(struct io_kiocb *req)
+static void __io_free_req_finish(struct io_kiocb *req)
 {
-       struct io_ring_ctx *ctx;
+       struct io_ring_ctx *ctx = req->ctx;
 
-       io_dismantle_req(req);
        __io_put_req_task(req);
-       ctx = req->ctx;
        if (likely(!io_is_fallback_req(req)))
                kmem_cache_free(req_cachep, req);
        else
@@ -1569,6 +1589,39 @@ static void __io_free_req(struct io_kiocb *req)
        percpu_ref_put(&ctx->refs);
 }
 
+static void io_req_task_file_table_put(struct callback_head *cb)
+{
+       struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
+       struct fs_struct *fs = req->work.fs;
+
+       spin_lock(&req->work.fs->lock);
+       if (--fs->users)
+               fs = NULL;
+       spin_unlock(&req->work.fs->lock);
+       if (fs)
+               free_fs_struct(fs);
+       req->work.fs = NULL;
+       __io_free_req_finish(req);
+}
+
+static void __io_free_req(struct io_kiocb *req)
+{
+       if (!io_dismantle_req(req)) {
+               __io_free_req_finish(req);
+       } else {
+               int ret;
+
+               init_task_work(&req->task_work, io_req_task_file_table_put);
+               ret = task_work_add(req->task, &req->task_work, TWA_RESUME);
+               if (unlikely(ret)) {
+                       struct task_struct *tsk;
+
+                       tsk = io_wq_get_task(req->ctx->io_wq);
+                       task_work_add(tsk, &req->task_work, 0);
+               }
+       }
+}
+
 static bool io_link_cancel_timeout(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
@@ -1598,6 +1651,7 @@ static bool __io_kill_linked_timeout(struct io_kiocb *req)
                return false;
 
        list_del_init(&link->link_list);
+       link->flags |= REQ_F_COMP_LOCKED;
        wake_ev = io_link_cancel_timeout(link);
        req->flags &= ~REQ_F_LINK_TIMEOUT;
        return wake_ev;
@@ -1656,6 +1710,7 @@ static void __io_fail_links(struct io_kiocb *req)
                trace_io_uring_fail_link(req, link);
 
                io_cqring_fill_event(link, -ECANCELED);
+               link->flags |= REQ_F_COMP_LOCKED;
                __io_double_put_req(link);
                req->flags &= ~REQ_F_LINK_TIMEOUT;
        }
@@ -1710,22 +1765,22 @@ static int io_req_task_work_add(struct io_kiocb *req, struct callback_head *cb)
 {
        struct task_struct *tsk = req->task;
        struct io_ring_ctx *ctx = req->ctx;
-       int ret, notify = TWA_RESUME;
+       int ret, notify;
 
        /*
-        * SQPOLL kernel thread doesn't need notification, just a wakeup.
-        * If we're not using an eventfd, then TWA_RESUME is always fine,
-        * as we won't have dependencies between request completions for
-        * other kernel wait conditions.
+        * SQPOLL kernel thread doesn't need notification, just a wakeup. For
+        * all other cases, use TWA_SIGNAL unconditionally to ensure we're
+        * processing task_work. There's no reliable way to tell if TWA_RESUME
+        * will do the job.
         */
-       if (ctx->flags & IORING_SETUP_SQPOLL)
-               notify = 0;
-       else if (ctx->cq_ev_fd)
+       notify = 0;
+       if (!(ctx->flags & IORING_SETUP_SQPOLL))
                notify = TWA_SIGNAL;
 
        ret = task_work_add(tsk, cb, notify);
        if (!ret)
                wake_up_process(tsk);
+
        return ret;
 }
 
@@ -1766,8 +1821,10 @@ static void __io_req_task_submit(struct io_kiocb *req)
 static void io_req_task_submit(struct callback_head *cb)
 {
        struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
+       struct io_ring_ctx *ctx = req->ctx;
 
        __io_req_task_submit(req);
+       percpu_ref_put(&ctx->refs);
 }
 
 static void io_req_task_queue(struct io_kiocb *req)
@@ -1775,6 +1832,7 @@ static void io_req_task_queue(struct io_kiocb *req)
        int ret;
 
        init_task_work(&req->task_work, io_req_task_submit);
+       percpu_ref_get(&req->ctx->refs);
 
        ret = io_req_task_work_add(req, &req->task_work);
        if (unlikely(ret)) {
@@ -1855,7 +1913,7 @@ static void io_req_free_batch(struct req_batch *rb, struct io_kiocb *req)
                req->flags &= ~REQ_F_TASK_PINNED;
        }
 
-       io_dismantle_req(req);
+       WARN_ON_ONCE(io_dismantle_req(req));
        rb->reqs[rb->to_free++] = req;
        if (unlikely(rb->to_free == ARRAY_SIZE(rb->reqs)))
                __io_req_free_batch_flush(req->ctx, rb);
@@ -2241,7 +2299,7 @@ static bool io_resubmit_prep(struct io_kiocb *req, int error)
        ret = io_import_iovec(rw, req, &iovec, &iter, false);
        if (ret < 0)
                goto end_req;
-       ret = io_setup_async_rw(req, ret, iovec, inline_vecs, &iter);
+       ret = io_setup_async_rw(req, iovec, inline_vecs, &iter, false);
        if (!ret)
                return true;
        kfree(iovec);
@@ -2263,6 +2321,8 @@ static void io_rw_resubmit(struct callback_head *cb)
                refcount_inc(&req->refs);
                io_queue_async_work(req);
        }
+
+       percpu_ref_put(&ctx->refs);
 }
 #endif
 
@@ -2275,6 +2335,8 @@ static bool io_rw_reissue(struct io_kiocb *req, long res)
                return false;
 
        init_task_work(&req->task_work, io_rw_resubmit);
+       percpu_ref_get(&req->ctx->refs);
+
        ret = io_req_task_work_add(req, &req->task_work);
        if (!ret)
                return true;
@@ -2527,6 +2589,14 @@ static void kiocb_done(struct kiocb *kiocb, ssize_t ret,
 {
        struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
 
+       /* add previously done IO, if any */
+       if (req->io && req->io->rw.bytes_done > 0) {
+               if (ret < 0)
+                       ret = req->io->rw.bytes_done;
+               else
+                       ret += req->io->rw.bytes_done;
+       }
+
        if (req->flags & REQ_F_CUR_POS)
                req->file->f_pos = kiocb->ki_pos;
        if (ret >= 0 && kiocb->ki_complete == io_complete_rw)
@@ -2758,6 +2828,13 @@ static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
        ssize_t ret;
        u8 opcode;
 
+       if (req->io) {
+               struct io_async_rw *iorw = &req->io->rw;
+
+               *iovec = NULL;
+               return iov_iter_count(&iorw->iter);
+       }
+
        opcode = req->opcode;
        if (opcode == IORING_OP_READ_FIXED || opcode == IORING_OP_WRITE_FIXED) {
                *iovec = NULL;
@@ -2783,14 +2860,6 @@ static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
                return ret < 0 ? ret : sqe_len;
        }
 
-       if (req->io) {
-               struct io_async_rw *iorw = &req->io->rw;
-
-               iov_iter_init(iter, rw, iorw->iov, iorw->nr_segs, iorw->size);
-               *iovec = NULL;
-               return iorw->size;
-       }
-
        if (req->flags & REQ_F_BUFFER_SELECT) {
                ret = io_iov_buffer_select(req, *iovec, needs_lock);
                if (!ret) {
@@ -2868,21 +2937,30 @@ static ssize_t loop_rw_iter(int rw, struct file *file, struct kiocb *kiocb,
        return ret;
 }
 
-static void io_req_map_rw(struct io_kiocb *req, ssize_t io_size,
-                         struct iovec *iovec, struct iovec *fast_iov,
-                         struct iov_iter *iter)
+static void io_req_map_rw(struct io_kiocb *req, const struct iovec *iovec,
+                         const struct iovec *fast_iov, struct iov_iter *iter)
 {
        struct io_async_rw *rw = &req->io->rw;
 
-       rw->nr_segs = iter->nr_segs;
-       rw->size = io_size;
+       memcpy(&rw->iter, iter, sizeof(*iter));
+       rw->free_iovec = NULL;
+       rw->bytes_done = 0;
+       /* can only be fixed buffers, no need to do anything */
+       if (iter->type == ITER_BVEC)
+               return;
        if (!iovec) {
-               rw->iov = rw->fast_iov;
-               if (rw->iov != fast_iov)
-                       memcpy(rw->iov, fast_iov,
+               unsigned iov_off = 0;
+
+               rw->iter.iov = rw->fast_iov;
+               if (iter->iov != fast_iov) {
+                       iov_off = iter->iov - fast_iov;
+                       rw->iter.iov += iov_off;
+               }
+               if (rw->fast_iov != fast_iov)
+                       memcpy(rw->fast_iov + iov_off, fast_iov + iov_off,
                               sizeof(struct iovec) * iter->nr_segs);
        } else {
-               rw->iov = iovec;
+               rw->free_iovec = iovec;
                req->flags |= REQ_F_NEED_CLEANUP;
        }
 }
@@ -2901,17 +2979,17 @@ static int io_alloc_async_ctx(struct io_kiocb *req)
        return  __io_alloc_async_ctx(req);
 }
 
-static int io_setup_async_rw(struct io_kiocb *req, ssize_t io_size,
-                            struct iovec *iovec, struct iovec *fast_iov,
-                            struct iov_iter *iter)
+static int io_setup_async_rw(struct io_kiocb *req, const struct iovec *iovec,
+                            const struct iovec *fast_iov,
+                            struct iov_iter *iter, bool force)
 {
-       if (!io_op_defs[req->opcode].async_ctx)
+       if (!force && !io_op_defs[req->opcode].async_ctx)
                return 0;
        if (!req->io) {
                if (__io_alloc_async_ctx(req))
                        return -ENOMEM;
 
-               io_req_map_rw(req, io_size, iovec, fast_iov, iter);
+               io_req_map_rw(req, iovec, fast_iov, iter);
        }
        return 0;
 }
@@ -2919,18 +2997,19 @@ static int io_setup_async_rw(struct io_kiocb *req, ssize_t io_size,
 static inline int io_rw_prep_async(struct io_kiocb *req, int rw,
                                   bool force_nonblock)
 {
-       struct io_async_ctx *io = req->io;
-       struct iov_iter iter;
+       struct io_async_rw *iorw = &req->io->rw;
        ssize_t ret;
 
-       io->rw.iov = io->rw.fast_iov;
+       iorw->iter.iov = iorw->fast_iov;
+       /* reset ->io around the iovec import, we don't want to use it */
        req->io = NULL;
-       ret = io_import_iovec(rw, req, &io->rw.iov, &iter, !force_nonblock);
-       req->io = io;
+       ret = io_import_iovec(rw, req, (struct iovec **) &iorw->iter.iov,
+                               &iorw->iter, !force_nonblock);
+       req->io = container_of(iorw, struct io_async_ctx, rw);
        if (unlikely(ret < 0))
                return ret;
 
-       io_req_map_rw(req, ret, io->rw.iov, io->rw.fast_iov, &iter);
+       io_req_map_rw(req, iorw->iter.iov, iorw->fast_iov, &iorw->iter);
        return 0;
 }
 
@@ -2952,6 +3031,16 @@ static int io_read_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        return io_rw_prep_async(req, READ, force_nonblock);
 }
 
+/*
+ * This is our waitqueue callback handler, registered through lock_page_async()
+ * when we initially tried to do the IO with the iocb armed our waitqueue.
+ * This gets called when the page is unlocked, and we generally expect that to
+ * happen when the page IO is completed and the page is now uptodate. This will
+ * queue a task_work based retry of the operation, attempting to copy the data
+ * again. If the latter fails because the page was NOT uptodate, then we will
+ * do a thread based blocking retry of the operation. That's the unexpected
+ * slow path.
+ */
 static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,
                             int sync, void *arg)
 {
@@ -2965,13 +3054,11 @@ static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,
        if (!wake_page_match(wpq, key))
                return 0;
 
-       /* Stop waking things up if the page is locked again */
-       if (test_bit(key->bit_nr, &key->page->flags))
-               return -1;
-
        list_del_init(&wait->entry);
 
        init_task_work(&req->task_work, io_req_task_submit);
+       percpu_ref_get(&req->ctx->refs);
+
        /* submit ref gets dropped, acquire a new one */
        refcount_inc(&req->refs);
        ret = io_req_task_work_add(req, &req->task_work);
@@ -3008,7 +3095,18 @@ static inline int kiocb_wait_page_queue_init(struct kiocb *kiocb,
        return -EOPNOTSUPP;
 }
 
-
+/*
+ * This controls whether a given IO request should be armed for async page
+ * based retry. If we return false here, the request is handed to the async
+ * worker threads for retry. If we're doing buffered reads on a regular file,
+ * we prepare a private wait_page_queue entry and retry the operation. This
+ * will either succeed because the page is now uptodate and unlocked, or it
+ * will register a callback when the page is unlocked at IO completion. Through
+ * that callback, io_uring uses task_work to setup a retry of the operation.
+ * That retry will attempt the buffered read again. The retry will generally
+ * succeed, or in rare cases where it fails, we then fall back to using the
+ * async worker threads for a blocking retry.
+ */
 static bool io_rw_should_retry(struct io_kiocb *req)
 {
        struct kiocb *kiocb = &req->rw.kiocb;
@@ -3018,8 +3116,8 @@ static bool io_rw_should_retry(struct io_kiocb *req)
        if (req->flags & REQ_F_NOWAIT)
                return false;
 
-       /* already tried, or we're doing O_DIRECT */
-       if (kiocb->ki_flags & (IOCB_DIRECT | IOCB_WAITQ))
+       /* Only for buffered IO */
+       if (kiocb->ki_flags & IOCB_DIRECT)
                return false;
        /*
         * just use poll if we can, and don't attempt if the fs doesn't
@@ -3028,13 +3126,6 @@ static bool io_rw_should_retry(struct io_kiocb *req)
        if (file_can_poll(req->file) || !(req->file->f_mode & FMODE_BUF_RASYNC))
                return false;
 
-       /*
-        * If request type doesn't require req->io to defer in general,
-        * we need to allocate it here
-        */
-       if (!req->io && __io_alloc_async_ctx(req))
-               return false;
-
        ret = kiocb_wait_page_queue_init(kiocb, &req->io->rw.wpq,
                                                io_async_buf_func, req);
        if (!ret) {
@@ -3049,7 +3140,10 @@ static int io_iter_do_read(struct io_kiocb *req, struct iov_iter *iter)
 {
        if (req->file->f_op->read_iter)
                return call_read_iter(req->file, &req->rw.kiocb, iter);
-       return loop_rw_iter(READ, req->file, &req->rw.kiocb, iter);
+       else if (req->file->f_op->read)
+               return loop_rw_iter(READ, req->file, &req->rw.kiocb, iter);
+       else
+               return -EINVAL;
 }
 
 static int io_read(struct io_kiocb *req, bool force_nonblock,
@@ -3057,16 +3151,19 @@ static int io_read(struct io_kiocb *req, bool force_nonblock,
 {
        struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
        struct kiocb *kiocb = &req->rw.kiocb;
-       struct iov_iter iter;
-       size_t iov_count;
+       struct iov_iter __iter, *iter = &__iter;
        ssize_t io_size, ret, ret2;
-       unsigned long nr_segs;
+       size_t iov_count;
+
+       if (req->io)
+               iter = &req->io->rw.iter;
 
-       ret = io_import_iovec(READ, req, &iovec, &iter, !force_nonblock);
+       ret = io_import_iovec(READ, req, &iovec, iter, !force_nonblock);
        if (ret < 0)
                return ret;
        io_size = ret;
        req->result = io_size;
+       ret = 0;
 
        /* Ensure we clear previously set non-block flag */
        if (!force_nonblock)
@@ -3076,40 +3173,70 @@ static int io_read(struct io_kiocb *req, bool force_nonblock,
        if (force_nonblock && !io_file_supports_async(req->file, READ))
                goto copy_iov;
 
-       iov_count = iov_iter_count(&iter);
-       nr_segs = iter.nr_segs;
+       iov_count = iov_iter_count(iter);
        ret = rw_verify_area(READ, req->file, &kiocb->ki_pos, iov_count);
        if (unlikely(ret))
                goto out_free;
 
-       ret2 = io_iter_do_read(req, &iter);
+       ret = io_iter_do_read(req, iter);
 
-       /* Catch -EAGAIN return for forced non-blocking submission */
-       if (!force_nonblock || (ret2 != -EAGAIN && ret2 != -EIO)) {
-               kiocb_done(kiocb, ret2, cs);
-       } else {
-               iter.count = iov_count;
-               iter.nr_segs = nr_segs;
-copy_iov:
-               ret = io_setup_async_rw(req, io_size, iovec, inline_vecs,
-                                       &iter);
+       if (!ret) {
+               goto done;
+       } else if (ret == -EIOCBQUEUED) {
+               ret = 0;
+               goto out_free;
+       } else if (ret == -EAGAIN) {
+               if (!force_nonblock)
+                       goto done;
+               ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false);
                if (ret)
                        goto out_free;
-               /* it's copied and will be cleaned with ->io */
-               iovec = NULL;
-               /* if we can retry, do so with the callbacks armed */
-               if (io_rw_should_retry(req)) {
-                       ret2 = io_iter_do_read(req, &iter);
-                       if (ret2 == -EIOCBQUEUED) {
-                               goto out_free;
-                       } else if (ret2 != -EAGAIN) {
-                               kiocb_done(kiocb, ret2, cs);
-                               goto out_free;
-                       }
-               }
+               return -EAGAIN;
+       } else if (ret < 0) {
+               goto out_free;
+       }
+
+       /* read it all, or we did blocking attempt. no retry. */
+       if (!iov_iter_count(iter) || !force_nonblock ||
+           (req->file->f_flags & O_NONBLOCK))
+               goto done;
+
+       io_size -= ret;
+copy_iov:
+       ret2 = io_setup_async_rw(req, iovec, inline_vecs, iter, true);
+       if (ret2) {
+               ret = ret2;
+               goto out_free;
+       }
+       /* it's copied and will be cleaned with ->io */
+       iovec = NULL;
+       /* now use our persistent iterator, if we aren't already */
+       iter = &req->io->rw.iter;
+retry:
+       req->io->rw.bytes_done += ret;
+       /* if we can retry, do so with the callbacks armed */
+       if (!io_rw_should_retry(req)) {
                kiocb->ki_flags &= ~IOCB_WAITQ;
                return -EAGAIN;
        }
+
+       /*
+        * Now retry read with the IOCB_WAITQ parts set in the iocb. If we
+        * get -EIOCBQUEUED, then we'll get a notification when the desired
+        * page gets unlocked. We can also get a partial read here, and if we
+        * do, then just retry at the new offset.
+        */
+       ret = io_iter_do_read(req, iter);
+       if (ret == -EIOCBQUEUED) {
+               ret = 0;
+               goto out_free;
+       } else if (ret > 0 && ret < io_size) {
+               /* we got some bytes, but not all. retry. */
+               goto retry;
+       }
+done:
+       kiocb_done(kiocb, ret, cs);
+       ret = 0;
 out_free:
        if (iovec)
                kfree(iovec);
@@ -3139,12 +3266,14 @@ static int io_write(struct io_kiocb *req, bool force_nonblock,
 {
        struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
        struct kiocb *kiocb = &req->rw.kiocb;
-       struct iov_iter iter;
+       struct iov_iter __iter, *iter = &__iter;
        size_t iov_count;
        ssize_t ret, ret2, io_size;
-       unsigned long nr_segs;
 
-       ret = io_import_iovec(WRITE, req, &iovec, &iter, !force_nonblock);
+       if (req->io)
+               iter = &req->io->rw.iter;
+
+       ret = io_import_iovec(WRITE, req, &iovec, iter, !force_nonblock);
        if (ret < 0)
                return ret;
        io_size = ret;
@@ -3163,8 +3292,7 @@ static int io_write(struct io_kiocb *req, bool force_nonblock,
            (req->flags & REQ_F_ISREG))
                goto copy_iov;
 
-       iov_count = iov_iter_count(&iter);
-       nr_segs = iter.nr_segs;
+       iov_count = iov_iter_count(iter);
        ret = rw_verify_area(WRITE, req->file, &kiocb->ki_pos, iov_count);
        if (unlikely(ret))
                goto out_free;
@@ -3185,9 +3313,11 @@ static int io_write(struct io_kiocb *req, bool force_nonblock,
        kiocb->ki_flags |= IOCB_WRITE;
 
        if (req->file->f_op->write_iter)
-               ret2 = call_write_iter(req->file, kiocb, &iter);
+               ret2 = call_write_iter(req->file, kiocb, iter);
+       else if (req->file->f_op->write)
+               ret2 = loop_rw_iter(WRITE, req->file, kiocb, iter);
        else
-               ret2 = loop_rw_iter(WRITE, req->file, kiocb, &iter);
+               ret2 = -EINVAL;
 
        /*
         * Raw bdev writes will return -EOPNOTSUPP for IOCB_NOWAIT. Just
@@ -3198,16 +3328,10 @@ static int io_write(struct io_kiocb *req, bool force_nonblock,
        if (!force_nonblock || ret2 != -EAGAIN) {
                kiocb_done(kiocb, ret2, cs);
        } else {
-               iter.count = iov_count;
-               iter.nr_segs = nr_segs;
 copy_iov:
-               ret = io_setup_async_rw(req, io_size, iovec, inline_vecs,
-                                       &iter);
-               if (ret)
-                       goto out_free;
-               /* it's copied and will be cleaned with ->io */
-               iovec = NULL;
-               return -EAGAIN;
+               ret = io_setup_async_rw(req, iovec, inline_vecs, iter, false);
+               if (!ret)
+                       return -EAGAIN;
        }
 out_free:
        if (iovec)
@@ -4488,6 +4612,8 @@ static int __io_async_wake(struct io_kiocb *req, struct io_poll_iocb *poll,
 
        req->result = mask;
        init_task_work(&req->task_work, func);
+       percpu_ref_get(&req->ctx->refs);
+
        /*
         * If this fails, then the task is exiting. When a task exits, the
         * work gets canceled, so just cancel this request as well instead
@@ -4526,9 +4652,24 @@ static bool io_poll_rewait(struct io_kiocb *req, struct io_poll_iocb *poll)
        return false;
 }
 
-static void io_poll_remove_double(struct io_kiocb *req, void *data)
+static struct io_poll_iocb *io_poll_get_double(struct io_kiocb *req)
 {
-       struct io_poll_iocb *poll = data;
+       /* pure poll stashes this in ->io, poll driven retry elsewhere */
+       if (req->opcode == IORING_OP_POLL_ADD)
+               return (struct io_poll_iocb *) req->io;
+       return req->apoll->double_poll;
+}
+
+static struct io_poll_iocb *io_poll_get_single(struct io_kiocb *req)
+{
+       if (req->opcode == IORING_OP_POLL_ADD)
+               return &req->poll;
+       return &req->apoll->poll;
+}
+
+static void io_poll_remove_double(struct io_kiocb *req)
+{
+       struct io_poll_iocb *poll = io_poll_get_double(req);
 
        lockdep_assert_held(&req->ctx->completion_lock);
 
@@ -4548,7 +4689,7 @@ static void io_poll_complete(struct io_kiocb *req, __poll_t mask, int error)
 {
        struct io_ring_ctx *ctx = req->ctx;
 
-       io_poll_remove_double(req, req->io);
+       io_poll_remove_double(req);
        req->poll.done = true;
        io_cqring_fill_event(req, error ? error : mangle_poll(mask));
        io_commit_cqring(ctx);
@@ -4575,18 +4716,20 @@ static void io_poll_task_handler(struct io_kiocb *req, struct io_kiocb **nxt)
 static void io_poll_task_func(struct callback_head *cb)
 {
        struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
+       struct io_ring_ctx *ctx = req->ctx;
        struct io_kiocb *nxt = NULL;
 
        io_poll_task_handler(req, &nxt);
        if (nxt)
                __io_req_task_submit(nxt);
+       percpu_ref_put(&ctx->refs);
 }
 
 static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
                               int sync, void *key)
 {
        struct io_kiocb *req = wait->private;
-       struct io_poll_iocb *poll = req->apoll->double_poll;
+       struct io_poll_iocb *poll = io_poll_get_single(req);
        __poll_t mask = key_to_poll(key);
 
        /* for instances that support it check for an event match first: */
@@ -4600,6 +4743,8 @@ static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
                done = list_empty(&poll->wait.entry);
                if (!done)
                        list_del_init(&poll->wait.entry);
+               /* make sure double remove sees this as being gone */
+               wait->private = NULL;
                spin_unlock(&poll->head->lock);
                if (!done)
                        __io_async_wake(req, poll, mask, io_poll_task_func);
@@ -4675,6 +4820,7 @@ static void io_async_task_func(struct callback_head *cb)
 
        if (io_poll_rewait(req, &apoll->poll)) {
                spin_unlock_irq(&ctx->completion_lock);
+               percpu_ref_put(&ctx->refs);
                return;
        }
 
@@ -4682,7 +4828,7 @@ static void io_async_task_func(struct callback_head *cb)
        if (hash_hashed(&req->hash_node))
                hash_del(&req->hash_node);
 
-       io_poll_remove_double(req, apoll->double_poll);
+       io_poll_remove_double(req);
        spin_unlock_irq(&ctx->completion_lock);
 
        if (!READ_ONCE(apoll->poll.canceled))
@@ -4690,6 +4836,7 @@ static void io_async_task_func(struct callback_head *cb)
        else
                __io_req_task_cancel(req, -ECANCELED);
 
+       percpu_ref_put(&ctx->refs);
        kfree(apoll->double_poll);
        kfree(apoll);
 }
@@ -4791,8 +4938,8 @@ static bool io_arm_poll_handler(struct io_kiocb *req)
 
        ret = __io_arm_poll_handler(req, &apoll->poll, &ipt, mask,
                                        io_async_wake);
-       if (ret) {
-               io_poll_remove_double(req, apoll->double_poll);
+       if (ret || ipt.error) {
+               io_poll_remove_double(req);
                spin_unlock_irq(&ctx->completion_lock);
                kfree(apoll->double_poll);
                kfree(apoll);
@@ -4824,14 +4971,13 @@ static bool io_poll_remove_one(struct io_kiocb *req)
 {
        bool do_complete;
 
+       io_poll_remove_double(req);
+
        if (req->opcode == IORING_OP_POLL_ADD) {
-               io_poll_remove_double(req, req->io);
                do_complete = __io_poll_remove_one(req, &req->poll);
        } else {
                struct async_poll *apoll = req->apoll;
 
-               io_poll_remove_double(req, apoll->double_poll);
-
                /* non-poll requests have submit ref still */
                do_complete = __io_poll_remove_one(req, &apoll->poll);
                if (do_complete) {
@@ -4845,6 +4991,7 @@ static bool io_poll_remove_one(struct io_kiocb *req)
                io_cqring_fill_event(req, -ECANCELED);
                io_commit_cqring(req->ctx);
                req->flags |= REQ_F_COMP_LOCKED;
+               req_set_fail_links(req);
                io_put_req(req);
        }
 
@@ -5017,6 +5164,23 @@ static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer)
        return HRTIMER_NORESTART;
 }
 
+static int __io_timeout_cancel(struct io_kiocb *req)
+{
+       int ret;
+
+       list_del_init(&req->timeout.list);
+
+       ret = hrtimer_try_to_cancel(&req->io->timeout.timer);
+       if (ret == -1)
+               return -EALREADY;
+
+       req_set_fail_links(req);
+       req->flags |= REQ_F_COMP_LOCKED;
+       io_cqring_fill_event(req, -ECANCELED);
+       io_put_req(req);
+       return 0;
+}
+
 static int io_timeout_cancel(struct io_ring_ctx *ctx, __u64 user_data)
 {
        struct io_kiocb *req;
@@ -5024,7 +5188,6 @@ static int io_timeout_cancel(struct io_ring_ctx *ctx, __u64 user_data)
 
        list_for_each_entry(req, &ctx->timeout_list, timeout.list) {
                if (user_data == req->user_data) {
-                       list_del_init(&req->timeout.list);
                        ret = 0;
                        break;
                }
@@ -5033,14 +5196,7 @@ static int io_timeout_cancel(struct io_ring_ctx *ctx, __u64 user_data)
        if (ret == -ENOENT)
                return ret;
 
-       ret = hrtimer_try_to_cancel(&req->io->timeout.timer);
-       if (ret == -1)
-               return -EALREADY;
-
-       req_set_fail_links(req);
-       io_cqring_fill_event(req, -ECANCELED);
-       io_put_req(req);
-       return 0;
+       return __io_timeout_cancel(req);
 }
 
 static int io_timeout_remove_prep(struct io_kiocb *req,
@@ -5481,8 +5637,8 @@ static void __io_clean_op(struct io_kiocb *req)
                case IORING_OP_WRITEV:
                case IORING_OP_WRITE_FIXED:
                case IORING_OP_WRITE:
-                       if (io->rw.iov != io->rw.fast_iov)
-                               kfree(io->rw.iov);
+                       if (io->rw.free_iovec)
+                               kfree(io->rw.free_iovec);
                        break;
                case IORING_OP_RECVMSG:
                case IORING_OP_SENDMSG:
@@ -5917,15 +6073,12 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer)
        return HRTIMER_NORESTART;
 }
 
-static void io_queue_linked_timeout(struct io_kiocb *req)
+static void __io_queue_linked_timeout(struct io_kiocb *req)
 {
-       struct io_ring_ctx *ctx = req->ctx;
-
        /*
         * If the list is now empty, then our linked request finished before
         * we got a chance to setup the timer
         */
-       spin_lock_irq(&ctx->completion_lock);
        if (!list_empty(&req->link_list)) {
                struct io_timeout_data *data = &req->io->timeout;
 
@@ -5933,6 +6086,14 @@ static void io_queue_linked_timeout(struct io_kiocb *req)
                hrtimer_start(&data->timer, timespec64_to_ktime(data->ts),
                                data->mode);
        }
+}
+
+static void io_queue_linked_timeout(struct io_kiocb *req)
+{
+       struct io_ring_ctx *ctx = req->ctx;
+
+       spin_lock_irq(&ctx->completion_lock);
+       __io_queue_linked_timeout(req);
        spin_unlock_irq(&ctx->completion_lock);
 
        /* drop submission reference */
@@ -7837,6 +7998,71 @@ static bool io_wq_files_match(struct io_wq_work *work, void *data)
        return work->files == files;
 }
 
+/*
+ * Returns true if 'preq' is the link parent of 'req'
+ */
+static bool io_match_link(struct io_kiocb *preq, struct io_kiocb *req)
+{
+       struct io_kiocb *link;
+
+       if (!(preq->flags & REQ_F_LINK_HEAD))
+               return false;
+
+       list_for_each_entry(link, &preq->link_list, link_list) {
+               if (link == req)
+                       return true;
+       }
+
+       return false;
+}
+
+/*
+ * We're looking to cancel 'req' because it's holding on to our files, but
+ * 'req' could be a link to another request. See if it is, and cancel that
+ * parent request if so.
+ */
+static bool io_poll_remove_link(struct io_ring_ctx *ctx, struct io_kiocb *req)
+{
+       struct hlist_node *tmp;
+       struct io_kiocb *preq;
+       bool found = false;
+       int i;
+
+       spin_lock_irq(&ctx->completion_lock);
+       for (i = 0; i < (1U << ctx->cancel_hash_bits); i++) {
+               struct hlist_head *list;
+
+               list = &ctx->cancel_hash[i];
+               hlist_for_each_entry_safe(preq, tmp, list, hash_node) {
+                       found = io_match_link(preq, req);
+                       if (found) {
+                               io_poll_remove_one(preq);
+                               break;
+                       }
+               }
+       }
+       spin_unlock_irq(&ctx->completion_lock);
+       return found;
+}
+
+static bool io_timeout_remove_link(struct io_ring_ctx *ctx,
+                                  struct io_kiocb *req)
+{
+       struct io_kiocb *preq;
+       bool found = false;
+
+       spin_lock_irq(&ctx->completion_lock);
+       list_for_each_entry(preq, &ctx->timeout_list, timeout.list) {
+               found = io_match_link(preq, req);
+               if (found) {
+                       __io_timeout_cancel(preq);
+                       break;
+               }
+       }
+       spin_unlock_irq(&ctx->completion_lock);
+       return found;
+}
+
 static void io_uring_cancel_files(struct io_ring_ctx *ctx,
                                  struct files_struct *files)
 {
@@ -7891,6 +8117,9 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx,
                        }
                } else {
                        io_wq_cancel_work(ctx->io_wq, &cancel_req->work);
+                       /* could be a link, check and remove if it is */
+                       if (!io_poll_remove_link(ctx, cancel_req))
+                               io_timeout_remove_link(ctx, cancel_req);
                        io_put_req(cancel_req);
                }
 
@@ -8171,6 +8400,10 @@ static int io_allocate_scq_urings(struct io_ring_ctx *ctx,
        struct io_rings *rings;
        size_t size, sq_array_offset;
 
+       /* make sure these are sane, as we already accounted them */
+       ctx->sq_entries = p->sq_entries;
+       ctx->cq_entries = p->cq_entries;
+
        size = rings_size(p->sq_entries, p->cq_entries, &sq_array_offset);
        if (size == SIZE_MAX)
                return -EOVERFLOW;
@@ -8187,8 +8420,6 @@ static int io_allocate_scq_urings(struct io_ring_ctx *ctx,
        rings->cq_ring_entries = p->cq_entries;
        ctx->sq_mask = rings->sq_ring_mask;
        ctx->cq_mask = rings->cq_ring_mask;
-       ctx->sq_entries = rings->sq_ring_entries;
-       ctx->cq_entries = rings->cq_ring_entries;
 
        size = array_size(sizeof(struct io_uring_sqe), p->sq_entries);
        if (size == SIZE_MAX) {
@@ -8317,6 +8548,16 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
        ctx->user = user;
        ctx->creds = get_current_cred();
 
+       /*
+        * Account memory _before_ installing the file descriptor. Once
+        * the descriptor is installed, it can get closed at any time. Also
+        * do this before hitting the general error path, as ring freeing
+        * will un-account as well.
+        */
+       io_account_mem(ctx, ring_pages(p->sq_entries, p->cq_entries),
+                      ACCT_LOCKED);
+       ctx->limit_mem = limit_mem;
+
        ret = io_allocate_scq_urings(ctx, p);
        if (ret)
                goto err;
@@ -8353,14 +8594,6 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
                goto err;
        }
 
-       /*
-        * Account memory _before_ installing the file descriptor. Once
-        * the descriptor is installed, it can get closed at any time.
-        */
-       io_account_mem(ctx, ring_pages(p->sq_entries, p->cq_entries),
-                      ACCT_LOCKED);
-       ctx->limit_mem = limit_mem;
-
        /*
         * Install ring fd as the very last thing, so we don't risk someone
         * having closed it before we finish setup
index 2112e57..e99e2a9 100644 (file)
@@ -2849,8 +2849,10 @@ static int may_open(const struct path *path, int acc_mode, int flag)
        case S_IFLNK:
                return -ELOOP;
        case S_IFDIR:
-               if (acc_mode & (MAY_WRITE | MAY_EXEC))
+               if (acc_mode & MAY_WRITE)
                        return -EISDIR;
+               if (acc_mode & MAY_EXEC)
+                       return -EACCES;
                break;
        case S_IFBLK:
        case S_IFCHR:
index 2433c3e..22d11fd 100644 (file)
@@ -30,7 +30,7 @@ nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o
 nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o
 nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
 nfsv4-$(CONFIG_NFS_V4_1)       += pnfs.o pnfs_dev.o pnfs_nfs.o
-nfsv4-$(CONFIG_NFS_V4_2)       += nfs42proc.o
+nfsv4-$(CONFIG_NFS_V4_2)       += nfs42proc.o nfs42xattr.o
 
 obj-$(CONFIG_PNFS_FILE_LAYOUT) += filelayout/
 obj-$(CONFIG_PNFS_BLOCK) += blocklayout/
index 9fb067a..ef9db13 100644 (file)
@@ -79,7 +79,7 @@ bl_resolve_deviceid(struct nfs_server *server, struct pnfs_block_volume *b,
                goto out_free_data;
 
        bl_msg = msg->data;
-       bl_msg->type = BL_DEVICE_MOUNT,
+       bl_msg->type = BL_DEVICE_MOUNT;
        bl_msg->totallen = b->simple.len;
        nfs4_encode_simple(msg->data + sizeof(*bl_msg), b);
 
index f1ff307..4b8cc93 100644 (file)
@@ -50,6 +50,7 @@
 #include "nfs.h"
 #include "netns.h"
 #include "sysfs.h"
+#include "nfs42.h"
 
 #define NFSDBG_FACILITY                NFSDBG_CLIENT
 
@@ -749,7 +750,7 @@ error:
 static void nfs_server_set_fsinfo(struct nfs_server *server,
                                  struct nfs_fsinfo *fsinfo)
 {
-       unsigned long max_rpc_payload;
+       unsigned long max_rpc_payload, raw_max_rpc_payload;
 
        /* Work out a lot of parameters */
        if (server->rsize == 0)
@@ -762,7 +763,9 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
        if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
                server->wsize = nfs_block_size(fsinfo->wtmax, NULL);
 
-       max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
+       raw_max_rpc_payload = rpc_max_payload(server->client);
+       max_rpc_payload = nfs_block_size(raw_max_rpc_payload, NULL);
+
        if (server->rsize > max_rpc_payload)
                server->rsize = max_rpc_payload;
        if (server->rsize > NFS_MAX_FILE_IO_SIZE)
@@ -795,6 +798,21 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
        server->clone_blksize = fsinfo->clone_blksize;
        /* We're airborne Set socket buffersize */
        rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
+
+#ifdef CONFIG_NFS_V4_2
+       /*
+        * Defaults until limited by the session parameters.
+        */
+       server->gxasize = min_t(unsigned int, raw_max_rpc_payload,
+                               XATTR_SIZE_MAX);
+       server->sxasize = min_t(unsigned int, raw_max_rpc_payload,
+                               XATTR_SIZE_MAX);
+       server->lxasize = min_t(unsigned int, raw_max_rpc_payload,
+                               nfs42_listxattr_xdrsize(XATTR_LIST_MAX));
+
+       if (fsinfo->xattr_support)
+               server->caps |= NFS_CAP_XATTR;
+#endif
 }
 
 /*
index 5a331da..a12f42e 100644 (file)
@@ -2460,7 +2460,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, co
        return NULL;
 }
 
-static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block)
+static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
        struct nfs_access_entry *cache;
@@ -2533,6 +2533,20 @@ out:
        return err;
 }
 
+int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct
+nfs_access_entry *res, bool may_block)
+{
+       int status;
+
+       status = nfs_access_get_cached_rcu(inode, cred, res);
+       if (status != 0)
+               status = nfs_access_get_cached_locked(inode, cred, res,
+                   may_block);
+
+       return status;
+}
+EXPORT_SYMBOL_GPL(nfs_access_get_cached);
+
 static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set)
 {
        struct nfs_inode *nfsi = NFS_I(inode);
@@ -2647,9 +2661,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
 
        trace_nfs_access_enter(inode);
 
-       status = nfs_access_get_cached_rcu(inode, cred, &cache);
-       if (status != 0)
-               status = nfs_access_get_cached(inode, cred, &cache, may_block);
+       status = nfs_access_get_cached(inode, cred, &cache, may_block);
        if (status == 0)
                goto out_cached;
 
@@ -2661,6 +2673,10 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
         * Determine which access bits we want to ask for...
         */
        cache.mask = NFS_ACCESS_READ | NFS_ACCESS_MODIFY | NFS_ACCESS_EXTEND;
+       if (nfs_server_capable(inode, NFS_CAP_XATTR)) {
+               cache.mask |= NFS_ACCESS_XAREAD | NFS_ACCESS_XAWRITE |
+                   NFS_ACCESS_XALIST;
+       }
        if (S_ISDIR(inode->i_mode))
                cache.mask |= NFS_ACCESS_DELETE | NFS_ACCESS_LOOKUP;
        else
index 1b79dd5..2d30a4d 100644 (file)
@@ -896,7 +896,7 @@ static ssize_t nfs_direct_write_schedule_iovec(struct nfs_direct_req *dreq,
  */
 ssize_t nfs_file_direct_write(struct kiocb *iocb, struct iov_iter *iter)
 {
-       ssize_t result = -EINVAL, requested;
+       ssize_t result, requested;
        size_t count;
        struct file *file = iocb->ki_filp;
        struct address_space *mapping = file->f_mapping;
index f96367a..63940a7 100644 (file)
@@ -140,6 +140,7 @@ static int
 nfs_file_flush(struct file *file, fl_owner_t id)
 {
        struct inode    *inode = file_inode(file);
+       errseq_t since;
 
        dprintk("NFS: flush(%pD2)\n", file);
 
@@ -148,7 +149,9 @@ nfs_file_flush(struct file *file, fl_owner_t id)
                return 0;
 
        /* Flush writes to the server and return any errors */
-       return nfs_wb_all(inode);
+       since = filemap_sample_wb_err(file->f_mapping);
+       nfs_wb_all(inode);
+       return filemap_check_wb_err(file->f_mapping, since);
 }
 
 ssize_t
@@ -587,12 +590,14 @@ static const struct vm_operations_struct nfs_file_vm_ops = {
        .page_mkwrite = nfs_vm_page_mkwrite,
 };
 
-static int nfs_need_check_write(struct file *filp, struct inode *inode)
+static int nfs_need_check_write(struct file *filp, struct inode *inode,
+                               int error)
 {
        struct nfs_open_context *ctx;
 
        ctx = nfs_file_open_context(filp);
-       if (nfs_ctx_key_to_expire(ctx, inode))
+       if (nfs_error_is_fatal_on_server(error) ||
+           nfs_ctx_key_to_expire(ctx, inode))
                return 1;
        return 0;
 }
@@ -603,6 +608,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
        struct inode *inode = file_inode(file);
        unsigned long written = 0;
        ssize_t result;
+       errseq_t since;
+       int error;
 
        result = nfs_key_timeout_notify(file, inode);
        if (result)
@@ -627,6 +634,7 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
        if (iocb->ki_pos > i_size_read(inode))
                nfs_revalidate_mapping(inode, file->f_mapping);
 
+       since = filemap_sample_wb_err(file->f_mapping);
        nfs_start_io_write(inode);
        result = generic_write_checks(iocb, from);
        if (result > 0) {
@@ -645,7 +653,8 @@ ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
                goto out;
 
        /* Return error values */
-       if (nfs_need_check_write(file, inode)) {
+       error = filemap_check_wb_err(file->f_mapping, since);
+       if (nfs_need_check_write(file, inode, error)) {
                int err = nfs_wb_all(inode);
                if (err < 0)
                        result = err;
index de03e44..9651455 100644 (file)
@@ -790,6 +790,19 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,
        return ff_layout_choose_any_ds_for_read(lseg, start_idx, best_idx);
 }
 
+static struct nfs4_pnfs_ds *
+ff_layout_get_ds_for_read(struct nfs_pageio_descriptor *pgio, int *best_idx)
+{
+       struct pnfs_layout_segment *lseg = pgio->pg_lseg;
+       struct nfs4_pnfs_ds *ds;
+
+       ds = ff_layout_choose_best_ds_for_read(lseg, pgio->pg_mirror_idx,
+                                              best_idx);
+       if (ds || !pgio->pg_mirror_idx)
+               return ds;
+       return ff_layout_choose_best_ds_for_read(lseg, 0, best_idx);
+}
+
 static void
 ff_layout_pg_get_read(struct nfs_pageio_descriptor *pgio,
                      struct nfs_page *req,
@@ -840,12 +853,11 @@ retry:
                        goto out_nolseg;
        }
 
-       ds = ff_layout_choose_best_ds_for_read(pgio->pg_lseg, 0, &ds_idx);
+       ds = ff_layout_get_ds_for_read(pgio, &ds_idx);
        if (!ds) {
                if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg))
                        goto out_mds;
-               pnfs_put_lseg(pgio->pg_lseg);
-               pgio->pg_lseg = NULL;
+               pnfs_generic_pg_cleanup(pgio);
                /* Sleep for 1 second before retrying */
                ssleep(1);
                goto retry;
@@ -871,8 +883,6 @@ out_mds:
                        0, NFS4_MAX_UINT64, IOMODE_READ,
                        NFS_I(pgio->pg_inode)->layout,
                        pgio->pg_lseg);
-       pnfs_put_lseg(pgio->pg_lseg);
-       pgio->pg_lseg = NULL;
        pgio->pg_maxretrans = 0;
        nfs_pageio_reset_read_mds(pgio);
 }
@@ -916,8 +926,7 @@ retry:
                if (!ds) {
                        if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg))
                                goto out_mds;
-                       pnfs_put_lseg(pgio->pg_lseg);
-                       pgio->pg_lseg = NULL;
+                       pnfs_generic_pg_cleanup(pgio);
                        /* Sleep for 1 second before retrying */
                        ssleep(1);
                        goto retry;
@@ -939,8 +948,6 @@ out_mds:
                        0, NFS4_MAX_UINT64, IOMODE_RW,
                        NFS_I(pgio->pg_inode)->layout,
                        pgio->pg_lseg);
-       pnfs_put_lseg(pgio->pg_lseg);
-       pgio->pg_lseg = NULL;
        pgio->pg_maxretrans = 0;
        nfs_pageio_reset_write_mds(pgio);
        pgio->pg_error = -EAGAIN;
@@ -953,8 +960,8 @@ ff_layout_pg_get_mirror_count_write(struct nfs_pageio_descriptor *pgio,
        if (!pgio->pg_lseg) {
                pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
                                                   nfs_req_openctx(req),
-                                                  0,
-                                                  NFS4_MAX_UINT64,
+                                                  req_offset(req),
+                                                  req->wb_bytes,
                                                   IOMODE_RW,
                                                   false,
                                                   GFP_NOFS);
@@ -1028,11 +1035,24 @@ static void ff_layout_reset_write(struct nfs_pgio_header *hdr, bool retry_pnfs)
        }
 }
 
+static void ff_layout_resend_pnfs_read(struct nfs_pgio_header *hdr)
+{
+       u32 idx = hdr->pgio_mirror_idx + 1;
+       int new_idx = 0;
+
+       if (ff_layout_choose_any_ds_for_read(hdr->lseg, idx + 1, &new_idx))
+               ff_layout_send_layouterror(hdr->lseg);
+       else
+               pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg);
+       pnfs_read_resend_pnfs(hdr, new_idx);
+}
+
 static void ff_layout_reset_read(struct nfs_pgio_header *hdr)
 {
        struct rpc_task *task = &hdr->task;
 
        pnfs_layoutcommit_inode(hdr->inode, false);
+       pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg);
 
        if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
                dprintk("%s Reset task %5u for i/o through MDS "
@@ -1234,6 +1254,12 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
                break;
        case NFS4ERR_NXIO:
                ff_layout_mark_ds_unreachable(lseg, idx);
+               /*
+                * Don't return the layout if this is a read and we still
+                * have layouts to try
+                */
+               if (opnum == OP_READ)
+                       break;
                /* Fallthrough */
        default:
                pnfs_error_mark_layout_for_return(lseg->pls_layout->plh_inode,
@@ -1247,7 +1273,6 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
 static int ff_layout_read_done_cb(struct rpc_task *task,
                                struct nfs_pgio_header *hdr)
 {
-       int new_idx = hdr->pgio_mirror_idx;
        int err;
 
        if (task->tk_status < 0) {
@@ -1267,10 +1292,6 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
        clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags);
        switch (err) {
        case -NFS4ERR_RESET_TO_PNFS:
-               if (ff_layout_choose_best_ds_for_read(hdr->lseg,
-                                       hdr->pgio_mirror_idx + 1,
-                                       &new_idx))
-                       goto out_layouterror;
                set_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags);
                return task->tk_status;
        case -NFS4ERR_RESET_TO_MDS:
@@ -1281,10 +1302,6 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
        }
 
        return 0;
-out_layouterror:
-       ff_layout_read_record_layoutstats_done(task, hdr);
-       ff_layout_send_layouterror(hdr->lseg);
-       hdr->pgio_mirror_idx = new_idx;
 out_eagain:
        rpc_restart_call_prepare(task);
        return -EAGAIN;
@@ -1411,10 +1428,9 @@ static void ff_layout_read_release(void *data)
        struct nfs_pgio_header *hdr = data;
 
        ff_layout_read_record_layoutstats_done(&hdr->task, hdr);
-       if (test_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags)) {
-               ff_layout_send_layouterror(hdr->lseg);
-               pnfs_read_resend_pnfs(hdr);
-       } else if (test_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags))
+       if (test_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags))
+               ff_layout_resend_pnfs_read(hdr);
+       else if (test_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags))
                ff_layout_reset_read(hdr);
        pnfs_generic_rw_release(data);
 }
index ccc88be..66949da 100644 (file)
@@ -982,7 +982,7 @@ static int nfs23_parse_monolithic(struct fs_context *fc,
                /*
                 * The legacy version 6 binary mount data from userspace has a
                 * field used only to transport selinux information into the
-                * the kernel.  To continue to support that functionality we
+                * kernel.  To continue to support that functionality we
                 * have a touch of selinux knowledge here in the NFS code. The
                 * userspace code converted context=blah to just blah so we are
                 * converting back to the full string selinux understands.
index 0bf1f83..aa64939 100644 (file)
@@ -193,6 +193,7 @@ bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
 
        return nfs_check_cache_invalid_not_delegated(inode, flags);
 }
+EXPORT_SYMBOL_GPL(nfs_check_cache_invalid);
 
 static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
 {
@@ -204,7 +205,8 @@ static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
                        flags &= ~NFS_INO_INVALID_OTHER;
                flags &= ~(NFS_INO_INVALID_CHANGE
                                | NFS_INO_INVALID_SIZE
-                               | NFS_INO_REVAL_PAGECACHE);
+                               | NFS_INO_REVAL_PAGECACHE
+                               | NFS_INO_INVALID_XATTR);
        }
 
        if (inode->i_mapping->nrpages == 0)
@@ -233,11 +235,13 @@ static void nfs_zap_caches_locked(struct inode *inode)
                                        | NFS_INO_INVALID_DATA
                                        | NFS_INO_INVALID_ACCESS
                                        | NFS_INO_INVALID_ACL
+                                       | NFS_INO_INVALID_XATTR
                                        | NFS_INO_REVAL_PAGECACHE);
        } else
                nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
                                        | NFS_INO_INVALID_ACCESS
                                        | NFS_INO_INVALID_ACL
+                                       | NFS_INO_INVALID_XATTR
                                        | NFS_INO_REVAL_PAGECACHE);
        nfs_zap_label_cache_locked(nfsi);
 }
@@ -542,6 +546,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
                        inode->i_gid = fattr->gid;
                else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
+               if (nfs_server_capable(inode, NFS_CAP_XATTR))
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_XATTR);
                if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
                        inode->i_blocks = fattr->du.nfs2.blocks;
                if (fattr->valid & NFS_ATTR_FATTR_SPACE_USED) {
@@ -794,8 +800,10 @@ int nfs_getattr(const struct path *path, struct kstat *stat,
 
        trace_nfs_getattr_enter(inode);
 
-       if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync)
+       if ((query_flags & AT_STATX_DONT_SYNC) && !force_sync) {
+               nfs_readdirplus_parent_cache_hit(path->dentry);
                goto out_no_update;
+       }
 
        /* Flush out writes to the server in order to update c/mtime.  */
        if ((request_mask & (STATX_CTIME|STATX_MTIME)) &&
@@ -1375,6 +1383,8 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                inode_set_iversion_raw(inode, fattr->change_attr);
                if (S_ISDIR(inode->i_mode))
                        nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
+               else if (nfs_server_capable(inode, NFS_CAP_XATTR))
+                       nfs_set_cache_invalid(inode, NFS_INO_INVALID_XATTR);
        }
        /* If we have atomic WCC data, we may update some attributes */
        ts = inode->i_ctime;
@@ -1892,7 +1902,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
                        if (!(have_writers || have_delegation)) {
                                invalid |= NFS_INO_INVALID_DATA
                                        | NFS_INO_INVALID_ACCESS
-                                       | NFS_INO_INVALID_ACL;
+                                       | NFS_INO_INVALID_ACL
+                                       | NFS_INO_INVALID_XATTR;
                                /* Force revalidate of all attributes */
                                save_cache_validity |= NFS_INO_INVALID_CTIME
                                        | NFS_INO_INVALID_MTIME
@@ -2095,6 +2106,9 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
 #if IS_ENABLED(CONFIG_NFS_V4)
        nfsi->nfs4_acl = NULL;
 #endif /* CONFIG_NFS_V4 */
+#ifdef CONFIG_NFS_V4_2
+       nfsi->xattr_cache = NULL;
+#endif
        return &nfsi->vfs_inode;
 }
 EXPORT_SYMBOL_GPL(nfs_alloc_inode);
index c891af9..0fe5aac 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef __LINUX_FS_NFS_NFS4_2_H
 #define __LINUX_FS_NFS_NFS4_2_H
 
+#include <linux/xattr.h>
+
 /*
  * FIXME:  four LAYOUTSTATS calls per compound at most! Do we need to support
  * more? Need to consider not to pre-alloc too much for a compound.
@@ -36,5 +38,27 @@ static inline bool nfs42_files_from_same_server(struct file *in,
        return nfs4_check_serverowner_major_id(c_in->cl_serverowner,
                                               c_out->cl_serverowner);
 }
+
+ssize_t nfs42_proc_getxattr(struct inode *inode, const char *name,
+                           void *buf, size_t buflen);
+int nfs42_proc_setxattr(struct inode *inode, const char *name,
+                       const void *buf, size_t buflen, int flags);
+ssize_t nfs42_proc_listxattrs(struct inode *inode, void *buf,
+                              size_t buflen, u64 *cookiep, bool *eofp);
+int nfs42_proc_removexattr(struct inode *inode, const char *name);
+
+/*
+ * Maximum XDR buffer size needed for a listxattr buffer of buflen size.
+ *
+ * The upper boundary is a buffer with all 1-byte sized attribute names.
+ * They would be 7 bytes long in the eventual buffer ("user.x\0"), and
+ * 8 bytes long XDR-encoded.
+ *
+ * Include the trailing eof word as well.
+ */
+static inline u32 nfs42_listxattr_xdrsize(u32 buflen)
+{
+       return ((buflen / (XATTR_USER_PREFIX_LEN + 2)) * 8) + 4;
+}
 #endif /* CONFIG_NFS_V4_2 */
 #endif /* __LINUX_FS_NFS_NFS4_2_H */
index e2ae54b..142225f 100644 (file)
@@ -17,6 +17,7 @@
 #include "nfs4session.h"
 #include "internal.h"
 #include "delegation.h"
+#include "nfs4trace.h"
 
 #define NFSDBG_FACILITY NFSDBG_PROC
 static int nfs42_do_offload_cancel_async(struct file *dst, nfs4_stateid *std);
@@ -714,7 +715,7 @@ nfs42_layoutstat_done(struct rpc_task *task, void *calldata)
 
        switch (task->tk_status) {
        case 0:
-               break;
+               return;
        case -NFS4ERR_BADHANDLE:
        case -ESTALE:
                pnfs_destroy_layout(NFS_I(inode));
@@ -760,6 +761,8 @@ nfs42_layoutstat_done(struct rpc_task *task, void *calldata)
        case -EOPNOTSUPP:
                NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTSTATS;
        }
+
+       trace_nfs4_layoutstats(inode, &data->args.stateid, task->tk_status);
 }
 
 static void
@@ -882,7 +885,7 @@ nfs42_layouterror_done(struct rpc_task *task, void *calldata)
 
        switch (task->tk_status) {
        case 0:
-               break;
+               return;
        case -NFS4ERR_BADHANDLE:
        case -ESTALE:
                pnfs_destroy_layout(NFS_I(inode));
@@ -926,6 +929,9 @@ nfs42_layouterror_done(struct rpc_task *task, void *calldata)
        case -EOPNOTSUPP:
                NFS_SERVER(inode)->caps &= ~NFS_CAP_LAYOUTERROR;
        }
+
+       trace_nfs4_layouterror(inode, &data->args.errors[0].stateid,
+                              task->tk_status);
 }
 
 static void
@@ -1088,3 +1094,251 @@ out_put_src_lock:
        nfs_put_lock_context(src_lock);
        return err;
 }
+
+#define NFS4XATTR_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)
+
+static int _nfs42_proc_removexattr(struct inode *inode, const char *name)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct nfs42_removexattrargs args = {
+               .fh = NFS_FH(inode),
+               .xattr_name = name,
+       };
+       struct nfs42_removexattrres res;
+       struct rpc_message msg = {
+               .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVEXATTR],
+               .rpc_argp = &args,
+               .rpc_resp = &res,
+       };
+       int ret;
+       unsigned long timestamp = jiffies;
+
+       ret = nfs4_call_sync(server->client, server, &msg, &args.seq_args,
+           &res.seq_res, 1);
+       if (!ret)
+               nfs4_update_changeattr(inode, &res.cinfo, timestamp, 0);
+
+       return ret;
+}
+
+static int _nfs42_proc_setxattr(struct inode *inode, const char *name,
+                               const void *buf, size_t buflen, int flags)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct page *pages[NFS4XATTR_MAXPAGES];
+       struct nfs42_setxattrargs arg = {
+               .fh             = NFS_FH(inode),
+               .xattr_pages    = pages,
+               .xattr_len      = buflen,
+               .xattr_name     = name,
+               .xattr_flags    = flags,
+       };
+       struct nfs42_setxattrres res;
+       struct rpc_message msg = {
+               .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_SETXATTR],
+               .rpc_argp       = &arg,
+               .rpc_resp       = &res,
+       };
+       int ret, np;
+       unsigned long timestamp = jiffies;
+
+       if (buflen > server->sxasize)
+               return -ERANGE;
+
+       if (buflen > 0) {
+               np = nfs4_buf_to_pages_noslab(buf, buflen, arg.xattr_pages);
+               if (np < 0)
+                       return np;
+       } else
+               np = 0;
+
+       ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
+           &res.seq_res, 1);
+
+       for (; np > 0; np--)
+               put_page(pages[np - 1]);
+
+       if (!ret)
+               nfs4_update_changeattr(inode, &res.cinfo, timestamp, 0);
+
+       return ret;
+}
+
+static ssize_t _nfs42_proc_getxattr(struct inode *inode, const char *name,
+                               void *buf, size_t buflen)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct page *pages[NFS4XATTR_MAXPAGES] = {};
+       struct nfs42_getxattrargs arg = {
+               .fh             = NFS_FH(inode),
+               .xattr_pages    = pages,
+               .xattr_len      = buflen,
+               .xattr_name     = name,
+       };
+       struct nfs42_getxattrres res;
+       struct rpc_message msg = {
+               .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_GETXATTR],
+               .rpc_argp       = &arg,
+               .rpc_resp       = &res,
+       };
+       int ret, np;
+
+       ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
+           &res.seq_res, 0);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * Normally, the caching is done one layer up, but for successful
+        * RPCS, always cache the result here, even if the caller was
+        * just querying the length, or if the reply was too big for
+        * the caller. This avoids a second RPC in the case of the
+        * common query-alloc-retrieve cycle for xattrs.
+        *
+        * Note that xattr_len is always capped to XATTR_SIZE_MAX.
+        */
+
+       nfs4_xattr_cache_add(inode, name, NULL, pages, res.xattr_len);
+
+       if (buflen) {
+               if (res.xattr_len > buflen)
+                       return -ERANGE;
+               _copy_from_pages(buf, pages, 0, res.xattr_len);
+       }
+
+       np = DIV_ROUND_UP(res.xattr_len, PAGE_SIZE);
+       while (--np >= 0)
+               __free_page(pages[np]);
+
+       return res.xattr_len;
+}
+
+static ssize_t _nfs42_proc_listxattrs(struct inode *inode, void *buf,
+                                size_t buflen, u64 *cookiep, bool *eofp)
+{
+       struct nfs_server *server = NFS_SERVER(inode);
+       struct page **pages;
+       struct nfs42_listxattrsargs arg = {
+               .fh             = NFS_FH(inode),
+               .cookie         = *cookiep,
+       };
+       struct nfs42_listxattrsres res = {
+               .eof = false,
+               .xattr_buf = buf,
+               .xattr_len = buflen,
+       };
+       struct rpc_message msg = {
+               .rpc_proc       = &nfs4_procedures[NFSPROC4_CLNT_LISTXATTRS],
+               .rpc_argp       = &arg,
+               .rpc_resp       = &res,
+       };
+       u32 xdrlen;
+       int ret, np;
+
+
+       res.scratch = alloc_page(GFP_KERNEL);
+       if (!res.scratch)
+               return -ENOMEM;
+
+       xdrlen = nfs42_listxattr_xdrsize(buflen);
+       if (xdrlen > server->lxasize)
+               xdrlen = server->lxasize;
+       np = xdrlen / PAGE_SIZE + 1;
+
+       pages = kcalloc(np, sizeof(struct page *), GFP_KERNEL);
+       if (pages == NULL) {
+               __free_page(res.scratch);
+               return -ENOMEM;
+       }
+
+       arg.xattr_pages = pages;
+       arg.count = xdrlen;
+
+       ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
+           &res.seq_res, 0);
+
+       if (ret >= 0) {
+               ret = res.copied;
+               *cookiep = res.cookie;
+               *eofp = res.eof;
+       }
+
+       while (--np >= 0) {
+               if (pages[np])
+                       __free_page(pages[np]);
+       }
+
+       __free_page(res.scratch);
+       kfree(pages);
+
+       return ret;
+
+}
+
+ssize_t nfs42_proc_getxattr(struct inode *inode, const char *name,
+                             void *buf, size_t buflen)
+{
+       struct nfs4_exception exception = { };
+       ssize_t err;
+
+       do {
+               err = _nfs42_proc_getxattr(inode, name, buf, buflen);
+               if (err >= 0)
+                       break;
+               err = nfs4_handle_exception(NFS_SERVER(inode), err,
+                               &exception);
+       } while (exception.retry);
+
+       return err;
+}
+
+int nfs42_proc_setxattr(struct inode *inode, const char *name,
+                             const void *buf, size_t buflen, int flags)
+{
+       struct nfs4_exception exception = { };
+       int err;
+
+       do {
+               err = _nfs42_proc_setxattr(inode, name, buf, buflen, flags);
+               if (!err)
+                       break;
+               err = nfs4_handle_exception(NFS_SERVER(inode), err,
+                               &exception);
+       } while (exception.retry);
+
+       return err;
+}
+
+ssize_t nfs42_proc_listxattrs(struct inode *inode, void *buf,
+                             size_t buflen, u64 *cookiep, bool *eofp)
+{
+       struct nfs4_exception exception = { };
+       ssize_t err;
+
+       do {
+               err = _nfs42_proc_listxattrs(inode, buf, buflen,
+                   cookiep, eofp);
+               if (err >= 0)
+                       break;
+               err = nfs4_handle_exception(NFS_SERVER(inode), err,
+                               &exception);
+       } while (exception.retry);
+
+       return err;
+}
+
+int nfs42_proc_removexattr(struct inode *inode, const char *name)
+{
+       struct nfs4_exception exception = { };
+       int err;
+
+       do {
+               err = _nfs42_proc_removexattr(inode, name);
+               if (!err)
+                       break;
+               err = nfs4_handle_exception(NFS_SERVER(inode), err,
+                               &exception);
+       } while (exception.retry);
+
+       return err;
+}
diff --git a/fs/nfs/nfs42xattr.c b/fs/nfs/nfs42xattr.c
new file mode 100644 (file)
index 0000000..8677799
--- /dev/null
@@ -0,0 +1,1056 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Copyright 2019, 2020 Amazon.com, Inc. or its affiliates. All rights reserved.
+ *
+ * User extended attribute client side cache functions.
+ *
+ * Author: Frank van der Linden <fllinden@amazon.com>
+ */
+#include <linux/errno.h>
+#include <linux/nfs_fs.h>
+#include <linux/hashtable.h>
+#include <linux/refcount.h>
+#include <uapi/linux/xattr.h>
+
+#include "nfs4_fs.h"
+#include "internal.h"
+
+/*
+ * User extended attributes client side caching is implemented by having
+ * a cache structure attached to NFS inodes. This structure is allocated
+ * when needed, and freed when the cache is zapped.
+ *
+ * The cache structure contains as hash table of entries, and a pointer
+ * to a special-cased entry for the listxattr cache.
+ *
+ * Accessing and allocating / freeing the caches is done via reference
+ * counting. The cache entries use a similar refcounting scheme.
+ *
+ * This makes freeing a cache, both from the shrinker and from the
+ * zap cache path, easy. It also means that, in current use cases,
+ * the large majority of inodes will not waste any memory, as they
+ * will never have any user extended attributes assigned to them.
+ *
+ * Attribute entries are hashed in to a simple hash table. They are
+ * also part of an LRU.
+ *
+ * There are three shrinkers.
+ *
+ * Two shrinkers deal with the cache entries themselves: one for
+ * large entries (> PAGE_SIZE), and one for smaller entries. The
+ * shrinker for the larger entries works more aggressively than
+ * those for the smaller entries.
+ *
+ * The other shrinker frees the cache structures themselves.
+ */
+
+/*
+ * 64 buckets is a good default. There is likely no reasonable
+ * workload that uses more than even 64 user extended attributes.
+ * You can certainly add a lot more - but you get what you ask for
+ * in those circumstances.
+ */
+#define NFS4_XATTR_HASH_SIZE   64
+
+#define NFSDBG_FACILITY        NFSDBG_XATTRCACHE
+
+struct nfs4_xattr_cache;
+struct nfs4_xattr_entry;
+
+struct nfs4_xattr_bucket {
+       spinlock_t lock;
+       struct hlist_head hlist;
+       struct nfs4_xattr_cache *cache;
+       bool draining;
+};
+
+struct nfs4_xattr_cache {
+       struct kref ref;
+       spinlock_t hash_lock;   /* protects hashtable and lru */
+       struct nfs4_xattr_bucket buckets[NFS4_XATTR_HASH_SIZE];
+       struct list_head lru;
+       struct list_head dispose;
+       atomic_long_t nent;
+       spinlock_t listxattr_lock;
+       struct inode *inode;
+       struct nfs4_xattr_entry *listxattr;
+};
+
+struct nfs4_xattr_entry {
+       struct kref ref;
+       struct hlist_node hnode;
+       struct list_head lru;
+       struct list_head dispose;
+       char *xattr_name;
+       void *xattr_value;
+       size_t xattr_size;
+       struct nfs4_xattr_bucket *bucket;
+       uint32_t flags;
+};
+
+#define        NFS4_XATTR_ENTRY_EXTVAL 0x0001
+
+/*
+ * LRU list of NFS inodes that have xattr caches.
+ */
+static struct list_lru nfs4_xattr_cache_lru;
+static struct list_lru nfs4_xattr_entry_lru;
+static struct list_lru nfs4_xattr_large_entry_lru;
+
+static struct kmem_cache *nfs4_xattr_cache_cachep;
+
+/*
+ * Hashing helper functions.
+ */
+static void
+nfs4_xattr_hash_init(struct nfs4_xattr_cache *cache)
+{
+       unsigned int i;
+
+       for (i = 0; i < NFS4_XATTR_HASH_SIZE; i++) {
+               INIT_HLIST_HEAD(&cache->buckets[i].hlist);
+               spin_lock_init(&cache->buckets[i].lock);
+               cache->buckets[i].cache = cache;
+               cache->buckets[i].draining = false;
+       }
+}
+
+/*
+ * Locking order:
+ * 1. inode i_lock or bucket lock
+ * 2. list_lru lock (taken by list_lru_* functions)
+ */
+
+/*
+ * Wrapper functions to add a cache entry to the right LRU.
+ */
+static bool
+nfs4_xattr_entry_lru_add(struct nfs4_xattr_entry *entry)
+{
+       struct list_lru *lru;
+
+       lru = (entry->flags & NFS4_XATTR_ENTRY_EXTVAL) ?
+           &nfs4_xattr_large_entry_lru : &nfs4_xattr_entry_lru;
+
+       return list_lru_add(lru, &entry->lru);
+}
+
+static bool
+nfs4_xattr_entry_lru_del(struct nfs4_xattr_entry *entry)
+{
+       struct list_lru *lru;
+
+       lru = (entry->flags & NFS4_XATTR_ENTRY_EXTVAL) ?
+           &nfs4_xattr_large_entry_lru : &nfs4_xattr_entry_lru;
+
+       return list_lru_del(lru, &entry->lru);
+}
+
+/*
+ * This function allocates cache entries. They are the normal
+ * extended attribute name/value pairs, but may also be a listxattr
+ * cache. Those allocations use the same entry so that they can be
+ * treated as one by the memory shrinker.
+ *
+ * xattr cache entries are allocated together with names. If the
+ * value fits in to one page with the entry structure and the name,
+ * it will also be part of the same allocation (kmalloc). This is
+ * expected to be the vast majority of cases. Larger allocations
+ * have a value pointer that is allocated separately by kvmalloc.
+ *
+ * Parameters:
+ *
+ * @name:  Name of the extended attribute. NULL for listxattr cache
+ *         entry.
+ * @value: Value of attribute, or listxattr cache. NULL if the
+ *         value is to be copied from pages instead.
+ * @pages: Pages to copy the value from, if not NULL. Passed in to
+ *        make it easier to copy the value after an RPC, even if
+ *        the value will not be passed up to application (e.g.
+ *        for a 'query' getxattr with NULL buffer).
+ * @len:   Length of the value. Can be 0 for zero-length attribues.
+ *         @value and @pages will be NULL if @len is 0.
+ */
+static struct nfs4_xattr_entry *
+nfs4_xattr_alloc_entry(const char *name, const void *value,
+                      struct page **pages, size_t len)
+{
+       struct nfs4_xattr_entry *entry;
+       void *valp;
+       char *namep;
+       size_t alloclen, slen;
+       char *buf;
+       uint32_t flags;
+
+       BUILD_BUG_ON(sizeof(struct nfs4_xattr_entry) +
+           XATTR_NAME_MAX + 1 > PAGE_SIZE);
+
+       alloclen = sizeof(struct nfs4_xattr_entry);
+       if (name != NULL) {
+               slen = strlen(name) + 1;
+               alloclen += slen;
+       } else
+               slen = 0;
+
+       if (alloclen + len <= PAGE_SIZE) {
+               alloclen += len;
+               flags = 0;
+       } else {
+               flags = NFS4_XATTR_ENTRY_EXTVAL;
+       }
+
+       buf = kmalloc(alloclen, GFP_KERNEL_ACCOUNT | GFP_NOFS);
+       if (buf == NULL)
+               return NULL;
+       entry = (struct nfs4_xattr_entry *)buf;
+
+       if (name != NULL) {
+               namep = buf + sizeof(struct nfs4_xattr_entry);
+               memcpy(namep, name, slen);
+       } else {
+               namep = NULL;
+       }
+
+
+       if (flags & NFS4_XATTR_ENTRY_EXTVAL) {
+               valp = kvmalloc(len, GFP_KERNEL_ACCOUNT | GFP_NOFS);
+               if (valp == NULL) {
+                       kfree(buf);
+                       return NULL;
+               }
+       } else if (len != 0) {
+               valp = buf + sizeof(struct nfs4_xattr_entry) + slen;
+       } else
+               valp = NULL;
+
+       if (valp != NULL) {
+               if (value != NULL)
+                       memcpy(valp, value, len);
+               else
+                       _copy_from_pages(valp, pages, 0, len);
+       }
+
+       entry->flags = flags;
+       entry->xattr_value = valp;
+       kref_init(&entry->ref);
+       entry->xattr_name = namep;
+       entry->xattr_size = len;
+       entry->bucket = NULL;
+       INIT_LIST_HEAD(&entry->lru);
+       INIT_LIST_HEAD(&entry->dispose);
+       INIT_HLIST_NODE(&entry->hnode);
+
+       return entry;
+}
+
+static void
+nfs4_xattr_free_entry(struct nfs4_xattr_entry *entry)
+{
+       if (entry->flags & NFS4_XATTR_ENTRY_EXTVAL)
+               kvfree(entry->xattr_value);
+       kfree(entry);
+}
+
+static void
+nfs4_xattr_free_entry_cb(struct kref *kref)
+{
+       struct nfs4_xattr_entry *entry;
+
+       entry = container_of(kref, struct nfs4_xattr_entry, ref);
+
+       if (WARN_ON(!list_empty(&entry->lru)))
+               return;
+
+       nfs4_xattr_free_entry(entry);
+}
+
+static void
+nfs4_xattr_free_cache_cb(struct kref *kref)
+{
+       struct nfs4_xattr_cache *cache;
+       int i;
+
+       cache = container_of(kref, struct nfs4_xattr_cache, ref);
+
+       for (i = 0; i < NFS4_XATTR_HASH_SIZE; i++) {
+               if (WARN_ON(!hlist_empty(&cache->buckets[i].hlist)))
+                       return;
+               cache->buckets[i].draining = false;
+       }
+
+       cache->listxattr = NULL;
+
+       kmem_cache_free(nfs4_xattr_cache_cachep, cache);
+
+}
+
+static struct nfs4_xattr_cache *
+nfs4_xattr_alloc_cache(void)
+{
+       struct nfs4_xattr_cache *cache;
+
+       cache = kmem_cache_alloc(nfs4_xattr_cache_cachep,
+           GFP_KERNEL_ACCOUNT | GFP_NOFS);
+       if (cache == NULL)
+               return NULL;
+
+       kref_init(&cache->ref);
+       atomic_long_set(&cache->nent, 0);
+
+       return cache;
+}
+
+/*
+ * Set the listxattr cache, which is a special-cased cache entry.
+ * The special value ERR_PTR(-ESTALE) is used to indicate that
+ * the cache is being drained - this prevents a new listxattr
+ * cache from being added to what is now a stale cache.
+ */
+static int
+nfs4_xattr_set_listcache(struct nfs4_xattr_cache *cache,
+                        struct nfs4_xattr_entry *new)
+{
+       struct nfs4_xattr_entry *old;
+       int ret = 1;
+
+       spin_lock(&cache->listxattr_lock);
+
+       old = cache->listxattr;
+
+       if (old == ERR_PTR(-ESTALE)) {
+               ret = 0;
+               goto out;
+       }
+
+       cache->listxattr = new;
+       if (new != NULL && new != ERR_PTR(-ESTALE))
+               nfs4_xattr_entry_lru_add(new);
+
+       if (old != NULL) {
+               nfs4_xattr_entry_lru_del(old);
+               kref_put(&old->ref, nfs4_xattr_free_entry_cb);
+       }
+out:
+       spin_unlock(&cache->listxattr_lock);
+
+       return ret;
+}
+
+/*
+ * Unlink a cache from its parent inode, clearing out an invalid
+ * cache. Must be called with i_lock held.
+ */
+static struct nfs4_xattr_cache *
+nfs4_xattr_cache_unlink(struct inode *inode)
+{
+       struct nfs_inode *nfsi;
+       struct nfs4_xattr_cache *oldcache;
+
+       nfsi = NFS_I(inode);
+
+       oldcache = nfsi->xattr_cache;
+       if (oldcache != NULL) {
+               list_lru_del(&nfs4_xattr_cache_lru, &oldcache->lru);
+               oldcache->inode = NULL;
+       }
+       nfsi->xattr_cache = NULL;
+       nfsi->cache_validity &= ~NFS_INO_INVALID_XATTR;
+
+       return oldcache;
+
+}
+
+/*
+ * Discard a cache. Called by get_cache() if there was an old,
+ * invalid cache. Can also be called from a shrinker callback.
+ *
+ * The cache is dead, it has already been unlinked from its inode,
+ * and no longer appears on the cache LRU list.
+ *
+ * Mark all buckets as draining, so that no new entries are added. This
+ * could still happen in the unlikely, but possible case that another
+ * thread had grabbed a reference before it was unlinked from the inode,
+ * and is still holding it for an add operation.
+ *
+ * Remove all entries from the LRU lists, so that there is no longer
+ * any way to 'find' this cache. Then, remove the entries from the hash
+ * table.
+ *
+ * At that point, the cache will remain empty and can be freed when the final
+ * reference drops, which is very likely the kref_put at the end of
+ * this function, or the one called immediately afterwards in the
+ * shrinker callback.
+ */
+static void
+nfs4_xattr_discard_cache(struct nfs4_xattr_cache *cache)
+{
+       unsigned int i;
+       struct nfs4_xattr_entry *entry;
+       struct nfs4_xattr_bucket *bucket;
+       struct hlist_node *n;
+
+       nfs4_xattr_set_listcache(cache, ERR_PTR(-ESTALE));
+
+       for (i = 0; i < NFS4_XATTR_HASH_SIZE; i++) {
+               bucket = &cache->buckets[i];
+
+               spin_lock(&bucket->lock);
+               bucket->draining = true;
+               hlist_for_each_entry_safe(entry, n, &bucket->hlist, hnode) {
+                       nfs4_xattr_entry_lru_del(entry);
+                       hlist_del_init(&entry->hnode);
+                       kref_put(&entry->ref, nfs4_xattr_free_entry_cb);
+               }
+               spin_unlock(&bucket->lock);
+       }
+
+       atomic_long_set(&cache->nent, 0);
+
+       kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+}
+
+/*
+ * Get a referenced copy of the cache structure. Avoid doing allocs
+ * while holding i_lock. Which means that we do some optimistic allocation,
+ * and might have to free the result in rare cases.
+ *
+ * This function only checks the NFS_INO_INVALID_XATTR cache validity bit
+ * and acts accordingly, replacing the cache when needed. For the read case
+ * (!add), this means that the caller must make sure that the cache
+ * is valid before caling this function. getxattr and listxattr call
+ * revalidate_inode to do this. The attribute cache timeout (for the
+ * non-delegated case) is expected to be dealt with in the revalidate
+ * call.
+ */
+
+static struct nfs4_xattr_cache *
+nfs4_xattr_get_cache(struct inode *inode, int add)
+{
+       struct nfs_inode *nfsi;
+       struct nfs4_xattr_cache *cache, *oldcache, *newcache;
+
+       nfsi = NFS_I(inode);
+
+       cache = oldcache = NULL;
+
+       spin_lock(&inode->i_lock);
+
+       if (nfsi->cache_validity & NFS_INO_INVALID_XATTR)
+               oldcache = nfs4_xattr_cache_unlink(inode);
+       else
+               cache = nfsi->xattr_cache;
+
+       if (cache != NULL)
+               kref_get(&cache->ref);
+
+       spin_unlock(&inode->i_lock);
+
+       if (add && cache == NULL) {
+               newcache = NULL;
+
+               cache = nfs4_xattr_alloc_cache();
+               if (cache == NULL)
+                       goto out;
+
+               spin_lock(&inode->i_lock);
+               if (nfsi->cache_validity & NFS_INO_INVALID_XATTR) {
+                       /*
+                        * The cache was invalidated again. Give up,
+                        * since what we want to enter is now likely
+                        * outdated anyway.
+                        */
+                       spin_unlock(&inode->i_lock);
+                       kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+                       cache = NULL;
+                       goto out;
+               }
+
+               /*
+                * Check if someone beat us to it.
+                */
+               if (nfsi->xattr_cache != NULL) {
+                       newcache = nfsi->xattr_cache;
+                       kref_get(&newcache->ref);
+               } else {
+                       kref_get(&cache->ref);
+                       nfsi->xattr_cache = cache;
+                       cache->inode = inode;
+                       list_lru_add(&nfs4_xattr_cache_lru, &cache->lru);
+               }
+
+               spin_unlock(&inode->i_lock);
+
+               /*
+                * If there was a race, throw away the cache we just
+                * allocated, and use the new one allocated by someone
+                * else.
+                */
+               if (newcache != NULL) {
+                       kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+                       cache = newcache;
+               }
+       }
+
+out:
+       /*
+        * Discard the now orphaned old cache.
+        */
+       if (oldcache != NULL)
+               nfs4_xattr_discard_cache(oldcache);
+
+       return cache;
+}
+
+static inline struct nfs4_xattr_bucket *
+nfs4_xattr_hash_bucket(struct nfs4_xattr_cache *cache, const char *name)
+{
+       return &cache->buckets[jhash(name, strlen(name), 0) &
+           (ARRAY_SIZE(cache->buckets) - 1)];
+}
+
+static struct nfs4_xattr_entry *
+nfs4_xattr_get_entry(struct nfs4_xattr_bucket *bucket, const char *name)
+{
+       struct nfs4_xattr_entry *entry;
+
+       entry = NULL;
+
+       hlist_for_each_entry(entry, &bucket->hlist, hnode) {
+               if (!strcmp(entry->xattr_name, name))
+                       break;
+       }
+
+       return entry;
+}
+
+static int
+nfs4_xattr_hash_add(struct nfs4_xattr_cache *cache,
+                   struct nfs4_xattr_entry *entry)
+{
+       struct nfs4_xattr_bucket *bucket;
+       struct nfs4_xattr_entry *oldentry = NULL;
+       int ret = 1;
+
+       bucket = nfs4_xattr_hash_bucket(cache, entry->xattr_name);
+       entry->bucket = bucket;
+
+       spin_lock(&bucket->lock);
+
+       if (bucket->draining) {
+               ret = 0;
+               goto out;
+       }
+
+       oldentry = nfs4_xattr_get_entry(bucket, entry->xattr_name);
+       if (oldentry != NULL) {
+               hlist_del_init(&oldentry->hnode);
+               nfs4_xattr_entry_lru_del(oldentry);
+       } else {
+               atomic_long_inc(&cache->nent);
+       }
+
+       hlist_add_head(&entry->hnode, &bucket->hlist);
+       nfs4_xattr_entry_lru_add(entry);
+
+out:
+       spin_unlock(&bucket->lock);
+
+       if (oldentry != NULL)
+               kref_put(&oldentry->ref, nfs4_xattr_free_entry_cb);
+
+       return ret;
+}
+
+static void
+nfs4_xattr_hash_remove(struct nfs4_xattr_cache *cache, const char *name)
+{
+       struct nfs4_xattr_bucket *bucket;
+       struct nfs4_xattr_entry *entry;
+
+       bucket = nfs4_xattr_hash_bucket(cache, name);
+
+       spin_lock(&bucket->lock);
+
+       entry = nfs4_xattr_get_entry(bucket, name);
+       if (entry != NULL) {
+               hlist_del_init(&entry->hnode);
+               nfs4_xattr_entry_lru_del(entry);
+               atomic_long_dec(&cache->nent);
+       }
+
+       spin_unlock(&bucket->lock);
+
+       if (entry != NULL)
+               kref_put(&entry->ref, nfs4_xattr_free_entry_cb);
+}
+
+static struct nfs4_xattr_entry *
+nfs4_xattr_hash_find(struct nfs4_xattr_cache *cache, const char *name)
+{
+       struct nfs4_xattr_bucket *bucket;
+       struct nfs4_xattr_entry *entry;
+
+       bucket = nfs4_xattr_hash_bucket(cache, name);
+
+       spin_lock(&bucket->lock);
+
+       entry = nfs4_xattr_get_entry(bucket, name);
+       if (entry != NULL)
+               kref_get(&entry->ref);
+
+       spin_unlock(&bucket->lock);
+
+       return entry;
+}
+
+/*
+ * Entry point to retrieve an entry from the cache.
+ */
+ssize_t nfs4_xattr_cache_get(struct inode *inode, const char *name, char *buf,
+                        ssize_t buflen)
+{
+       struct nfs4_xattr_cache *cache;
+       struct nfs4_xattr_entry *entry;
+       ssize_t ret;
+
+       cache = nfs4_xattr_get_cache(inode, 0);
+       if (cache == NULL)
+               return -ENOENT;
+
+       ret = 0;
+       entry = nfs4_xattr_hash_find(cache, name);
+
+       if (entry != NULL) {
+               dprintk("%s: cache hit '%s', len %lu\n", __func__,
+                   entry->xattr_name, (unsigned long)entry->xattr_size);
+               if (buflen == 0) {
+                       /* Length probe only */
+                       ret = entry->xattr_size;
+               } else if (buflen < entry->xattr_size)
+                       ret = -ERANGE;
+               else {
+                       memcpy(buf, entry->xattr_value, entry->xattr_size);
+                       ret = entry->xattr_size;
+               }
+               kref_put(&entry->ref, nfs4_xattr_free_entry_cb);
+       } else {
+               dprintk("%s: cache miss '%s'\n", __func__, name);
+               ret = -ENOENT;
+       }
+
+       kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+
+       return ret;
+}
+
+/*
+ * Retrieve a cached list of xattrs from the cache.
+ */
+ssize_t nfs4_xattr_cache_list(struct inode *inode, char *buf, ssize_t buflen)
+{
+       struct nfs4_xattr_cache *cache;
+       struct nfs4_xattr_entry *entry;
+       ssize_t ret;
+
+       cache = nfs4_xattr_get_cache(inode, 0);
+       if (cache == NULL)
+               return -ENOENT;
+
+       spin_lock(&cache->listxattr_lock);
+
+       entry = cache->listxattr;
+
+       if (entry != NULL && entry != ERR_PTR(-ESTALE)) {
+               if (buflen == 0) {
+                       /* Length probe only */
+                       ret = entry->xattr_size;
+               } else if (entry->xattr_size > buflen)
+                       ret = -ERANGE;
+               else {
+                       memcpy(buf, entry->xattr_value, entry->xattr_size);
+                       ret = entry->xattr_size;
+               }
+       } else {
+               ret = -ENOENT;
+       }
+
+       spin_unlock(&cache->listxattr_lock);
+
+       kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+
+       return ret;
+}
+
+/*
+ * Add an xattr to the cache.
+ *
+ * This also invalidates the xattr list cache.
+ */
+void nfs4_xattr_cache_add(struct inode *inode, const char *name,
+                         const char *buf, struct page **pages, ssize_t buflen)
+{
+       struct nfs4_xattr_cache *cache;
+       struct nfs4_xattr_entry *entry;
+
+       dprintk("%s: add '%s' len %lu\n", __func__,
+           name, (unsigned long)buflen);
+
+       cache = nfs4_xattr_get_cache(inode, 1);
+       if (cache == NULL)
+               return;
+
+       entry = nfs4_xattr_alloc_entry(name, buf, pages, buflen);
+       if (entry == NULL)
+               goto out;
+
+       (void)nfs4_xattr_set_listcache(cache, NULL);
+
+       if (!nfs4_xattr_hash_add(cache, entry))
+               kref_put(&entry->ref, nfs4_xattr_free_entry_cb);
+
+out:
+       kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+}
+
+
+/*
+ * Remove an xattr from the cache.
+ *
+ * This also invalidates the xattr list cache.
+ */
+void nfs4_xattr_cache_remove(struct inode *inode, const char *name)
+{
+       struct nfs4_xattr_cache *cache;
+
+       dprintk("%s: remove '%s'\n", __func__, name);
+
+       cache = nfs4_xattr_get_cache(inode, 0);
+       if (cache == NULL)
+               return;
+
+       (void)nfs4_xattr_set_listcache(cache, NULL);
+       nfs4_xattr_hash_remove(cache, name);
+
+       kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+}
+
+/*
+ * Cache listxattr output, replacing any possible old one.
+ */
+void nfs4_xattr_cache_set_list(struct inode *inode, const char *buf,
+                              ssize_t buflen)
+{
+       struct nfs4_xattr_cache *cache;
+       struct nfs4_xattr_entry *entry;
+
+       cache = nfs4_xattr_get_cache(inode, 1);
+       if (cache == NULL)
+               return;
+
+       entry = nfs4_xattr_alloc_entry(NULL, buf, NULL, buflen);
+       if (entry == NULL)
+               goto out;
+
+       /*
+        * This is just there to be able to get to bucket->cache,
+        * which is obviously the same for all buckets, so just
+        * use bucket 0.
+        */
+       entry->bucket = &cache->buckets[0];
+
+       if (!nfs4_xattr_set_listcache(cache, entry))
+               kref_put(&entry->ref, nfs4_xattr_free_entry_cb);
+
+out:
+       kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+}
+
+/*
+ * Zap the entire cache. Called when an inode is evicted.
+ */
+void nfs4_xattr_cache_zap(struct inode *inode)
+{
+       struct nfs4_xattr_cache *oldcache;
+
+       spin_lock(&inode->i_lock);
+       oldcache = nfs4_xattr_cache_unlink(inode);
+       spin_unlock(&inode->i_lock);
+
+       if (oldcache)
+               nfs4_xattr_discard_cache(oldcache);
+}
+
+/*
+ * The entry LRU is shrunk more aggressively than the cache LRU,
+ * by settings @seeks to 1.
+ *
+ * Cache structures are freed only when they've become empty, after
+ * pruning all but one entry.
+ */
+
+static unsigned long nfs4_xattr_cache_count(struct shrinker *shrink,
+                                           struct shrink_control *sc);
+static unsigned long nfs4_xattr_entry_count(struct shrinker *shrink,
+                                           struct shrink_control *sc);
+static unsigned long nfs4_xattr_cache_scan(struct shrinker *shrink,
+                                          struct shrink_control *sc);
+static unsigned long nfs4_xattr_entry_scan(struct shrinker *shrink,
+                                          struct shrink_control *sc);
+
+static struct shrinker nfs4_xattr_cache_shrinker = {
+       .count_objects  = nfs4_xattr_cache_count,
+       .scan_objects   = nfs4_xattr_cache_scan,
+       .seeks          = DEFAULT_SEEKS,
+       .flags          = SHRINKER_MEMCG_AWARE,
+};
+
+static struct shrinker nfs4_xattr_entry_shrinker = {
+       .count_objects  = nfs4_xattr_entry_count,
+       .scan_objects   = nfs4_xattr_entry_scan,
+       .seeks          = DEFAULT_SEEKS,
+       .batch          = 512,
+       .flags          = SHRINKER_MEMCG_AWARE,
+};
+
+static struct shrinker nfs4_xattr_large_entry_shrinker = {
+       .count_objects  = nfs4_xattr_entry_count,
+       .scan_objects   = nfs4_xattr_entry_scan,
+       .seeks          = 1,
+       .batch          = 512,
+       .flags          = SHRINKER_MEMCG_AWARE,
+};
+
+static enum lru_status
+cache_lru_isolate(struct list_head *item,
+       struct list_lru_one *lru, spinlock_t *lru_lock, void *arg)
+{
+       struct list_head *dispose = arg;
+       struct inode *inode;
+       struct nfs4_xattr_cache *cache = container_of(item,
+           struct nfs4_xattr_cache, lru);
+
+       if (atomic_long_read(&cache->nent) > 1)
+               return LRU_SKIP;
+
+       /*
+        * If a cache structure is on the LRU list, we know that
+        * its inode is valid. Try to lock it to break the link.
+        * Since we're inverting the lock order here, only try.
+        */
+       inode = cache->inode;
+
+       if (!spin_trylock(&inode->i_lock))
+               return LRU_SKIP;
+
+       kref_get(&cache->ref);
+
+       cache->inode = NULL;
+       NFS_I(inode)->xattr_cache = NULL;
+       NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_XATTR;
+       list_lru_isolate(lru, &cache->lru);
+
+       spin_unlock(&inode->i_lock);
+
+       list_add_tail(&cache->dispose, dispose);
+       return LRU_REMOVED;
+}
+
+static unsigned long
+nfs4_xattr_cache_scan(struct shrinker *shrink, struct shrink_control *sc)
+{
+       LIST_HEAD(dispose);
+       unsigned long freed;
+       struct nfs4_xattr_cache *cache;
+
+       freed = list_lru_shrink_walk(&nfs4_xattr_cache_lru, sc,
+           cache_lru_isolate, &dispose);
+       while (!list_empty(&dispose)) {
+               cache = list_first_entry(&dispose, struct nfs4_xattr_cache,
+                   dispose);
+               list_del_init(&cache->dispose);
+               nfs4_xattr_discard_cache(cache);
+               kref_put(&cache->ref, nfs4_xattr_free_cache_cb);
+       }
+
+       return freed;
+}
+
+
+static unsigned long
+nfs4_xattr_cache_count(struct shrinker *shrink, struct shrink_control *sc)
+{
+       unsigned long count;
+
+       count = list_lru_count(&nfs4_xattr_cache_lru);
+       return vfs_pressure_ratio(count);
+}
+
+static enum lru_status
+entry_lru_isolate(struct list_head *item,
+       struct list_lru_one *lru, spinlock_t *lru_lock, void *arg)
+{
+       struct list_head *dispose = arg;
+       struct nfs4_xattr_bucket *bucket;
+       struct nfs4_xattr_cache *cache;
+       struct nfs4_xattr_entry *entry = container_of(item,
+           struct nfs4_xattr_entry, lru);
+
+       bucket = entry->bucket;
+       cache = bucket->cache;
+
+       /*
+        * Unhook the entry from its parent (either a cache bucket
+        * or a cache structure if it's a listxattr buf), so that
+        * it's no longer found. Then add it to the isolate list,
+        * to be freed later.
+        *
+        * In both cases, we're reverting lock order, so use
+        * trylock and skip the entry if we can't get the lock.
+        */
+       if (entry->xattr_name != NULL) {
+               /* Regular cache entry */
+               if (!spin_trylock(&bucket->lock))
+                       return LRU_SKIP;
+
+               kref_get(&entry->ref);
+
+               hlist_del_init(&entry->hnode);
+               atomic_long_dec(&cache->nent);
+               list_lru_isolate(lru, &entry->lru);
+
+               spin_unlock(&bucket->lock);
+       } else {
+               /* Listxattr cache entry */
+               if (!spin_trylock(&cache->listxattr_lock))
+                       return LRU_SKIP;
+
+               kref_get(&entry->ref);
+
+               cache->listxattr = NULL;
+               list_lru_isolate(lru, &entry->lru);
+
+               spin_unlock(&cache->listxattr_lock);
+       }
+
+       list_add_tail(&entry->dispose, dispose);
+       return LRU_REMOVED;
+}
+
+static unsigned long
+nfs4_xattr_entry_scan(struct shrinker *shrink, struct shrink_control *sc)
+{
+       LIST_HEAD(dispose);
+       unsigned long freed;
+       struct nfs4_xattr_entry *entry;
+       struct list_lru *lru;
+
+       lru = (shrink == &nfs4_xattr_large_entry_shrinker) ?
+           &nfs4_xattr_large_entry_lru : &nfs4_xattr_entry_lru;
+
+       freed = list_lru_shrink_walk(lru, sc, entry_lru_isolate, &dispose);
+
+       while (!list_empty(&dispose)) {
+               entry = list_first_entry(&dispose, struct nfs4_xattr_entry,
+                   dispose);
+               list_del_init(&entry->dispose);
+
+               /*
+                * Drop two references: the one that we just grabbed
+                * in entry_lru_isolate, and the one that was set
+                * when the entry was first allocated.
+                */
+               kref_put(&entry->ref, nfs4_xattr_free_entry_cb);
+               kref_put(&entry->ref, nfs4_xattr_free_entry_cb);
+       }
+
+       return freed;
+}
+
+static unsigned long
+nfs4_xattr_entry_count(struct shrinker *shrink, struct shrink_control *sc)
+{
+       unsigned long count;
+       struct list_lru *lru;
+
+       lru = (shrink == &nfs4_xattr_large_entry_shrinker) ?
+           &nfs4_xattr_large_entry_lru : &nfs4_xattr_entry_lru;
+
+       count = list_lru_count(lru);
+       return vfs_pressure_ratio(count);
+}
+
+
+static void nfs4_xattr_cache_init_once(void *p)
+{
+       struct nfs4_xattr_cache *cache = (struct nfs4_xattr_cache *)p;
+
+       spin_lock_init(&cache->listxattr_lock);
+       atomic_long_set(&cache->nent, 0);
+       nfs4_xattr_hash_init(cache);
+       cache->listxattr = NULL;
+       INIT_LIST_HEAD(&cache->lru);
+       INIT_LIST_HEAD(&cache->dispose);
+}
+
+int __init nfs4_xattr_cache_init(void)
+{
+       int ret = 0;
+
+       nfs4_xattr_cache_cachep = kmem_cache_create("nfs4_xattr_cache_cache",
+           sizeof(struct nfs4_xattr_cache), 0,
+           (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD|SLAB_ACCOUNT),
+           nfs4_xattr_cache_init_once);
+       if (nfs4_xattr_cache_cachep == NULL)
+               return -ENOMEM;
+
+       ret = list_lru_init_memcg(&nfs4_xattr_large_entry_lru,
+           &nfs4_xattr_large_entry_shrinker);
+       if (ret)
+               goto out4;
+
+       ret = list_lru_init_memcg(&nfs4_xattr_entry_lru,
+           &nfs4_xattr_entry_shrinker);
+       if (ret)
+               goto out3;
+
+       ret = list_lru_init_memcg(&nfs4_xattr_cache_lru,
+           &nfs4_xattr_cache_shrinker);
+       if (ret)
+               goto out2;
+
+       ret = register_shrinker(&nfs4_xattr_cache_shrinker);
+       if (ret)
+               goto out1;
+
+       ret = register_shrinker(&nfs4_xattr_entry_shrinker);
+       if (ret)
+               goto out;
+
+       ret = register_shrinker(&nfs4_xattr_large_entry_shrinker);
+       if (!ret)
+               return 0;
+
+       unregister_shrinker(&nfs4_xattr_entry_shrinker);
+out:
+       unregister_shrinker(&nfs4_xattr_cache_shrinker);
+out1:
+       list_lru_destroy(&nfs4_xattr_cache_lru);
+out2:
+       list_lru_destroy(&nfs4_xattr_entry_lru);
+out3:
+       list_lru_destroy(&nfs4_xattr_large_entry_lru);
+out4:
+       kmem_cache_destroy(nfs4_xattr_cache_cachep);
+
+       return ret;
+}
+
+void nfs4_xattr_cache_exit(void)
+{
+       unregister_shrinker(&nfs4_xattr_entry_shrinker);
+       unregister_shrinker(&nfs4_xattr_cache_shrinker);
+       list_lru_destroy(&nfs4_xattr_entry_lru);
+       list_lru_destroy(&nfs4_xattr_cache_lru);
+       kmem_cache_destroy(nfs4_xattr_cache_cachep);
+}
index c03f324..cc50085 100644 (file)
                                         decode_clone_maxsz + \
                                         decode_getattr_maxsz)
 
+/* Not limited by NFS itself, limited by the generic xattr code */
+#define nfs4_xattr_name_maxsz   XDR_QUADLEN(XATTR_NAME_MAX)
+
+#define encode_getxattr_maxsz   (op_encode_hdr_maxsz + 1 + \
+                                nfs4_xattr_name_maxsz)
+#define decode_getxattr_maxsz   (op_decode_hdr_maxsz + 1 + 1)
+#define encode_setxattr_maxsz   (op_encode_hdr_maxsz + \
+                                1 + nfs4_xattr_name_maxsz + 1)
+#define decode_setxattr_maxsz   (op_decode_hdr_maxsz + decode_change_info_maxsz)
+#define encode_listxattrs_maxsz  (op_encode_hdr_maxsz + 2 + 1)
+#define decode_listxattrs_maxsz  (op_decode_hdr_maxsz + 2 + 1 + 1)
+#define encode_removexattr_maxsz (op_encode_hdr_maxsz + 1 + \
+                                 nfs4_xattr_name_maxsz)
+#define decode_removexattr_maxsz (op_decode_hdr_maxsz + \
+                                 decode_change_info_maxsz)
+
+#define NFS4_enc_getxattr_sz   (compound_encode_hdr_maxsz + \
+                               encode_sequence_maxsz + \
+                               encode_putfh_maxsz + \
+                               encode_getxattr_maxsz)
+#define NFS4_dec_getxattr_sz   (compound_decode_hdr_maxsz + \
+                               decode_sequence_maxsz + \
+                               decode_putfh_maxsz + \
+                               decode_getxattr_maxsz)
+#define NFS4_enc_setxattr_sz   (compound_encode_hdr_maxsz + \
+                               encode_sequence_maxsz + \
+                               encode_putfh_maxsz + \
+                               encode_setxattr_maxsz)
+#define NFS4_dec_setxattr_sz   (compound_decode_hdr_maxsz + \
+                               decode_sequence_maxsz + \
+                               decode_putfh_maxsz + \
+                               decode_setxattr_maxsz)
+#define NFS4_enc_listxattrs_sz (compound_encode_hdr_maxsz + \
+                               encode_sequence_maxsz + \
+                               encode_putfh_maxsz + \
+                               encode_listxattrs_maxsz)
+#define NFS4_dec_listxattrs_sz (compound_decode_hdr_maxsz + \
+                               decode_sequence_maxsz + \
+                               decode_putfh_maxsz + \
+                               decode_listxattrs_maxsz)
+#define NFS4_enc_removexattr_sz        (compound_encode_hdr_maxsz + \
+                               encode_sequence_maxsz + \
+                               encode_putfh_maxsz + \
+                               encode_removexattr_maxsz)
+#define NFS4_dec_removexattr_sz        (compound_decode_hdr_maxsz + \
+                               decode_sequence_maxsz + \
+                               decode_putfh_maxsz + \
+                               decode_removexattr_maxsz)
+
+/*
+ * These values specify the maximum amount of data that is not
+ * associated with the extended attribute name or extended
+ * attribute list in the SETXATTR, GETXATTR and LISTXATTR
+ * respectively.
+ */
+const u32 nfs42_maxsetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
+                                       compound_encode_hdr_maxsz +
+                                       encode_sequence_maxsz +
+                                       encode_putfh_maxsz + 1 +
+                                       nfs4_xattr_name_maxsz)
+                                       * XDR_UNIT);
+
+const u32 nfs42_maxgetxattr_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
+                                       compound_decode_hdr_maxsz +
+                                       decode_sequence_maxsz +
+                                       decode_putfh_maxsz + 1) * XDR_UNIT);
+
+const u32 nfs42_maxlistxattrs_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
+                                       compound_decode_hdr_maxsz +
+                                       decode_sequence_maxsz +
+                                       decode_putfh_maxsz + 3) * XDR_UNIT);
+
 static void encode_fallocate(struct xdr_stream *xdr,
                             const struct nfs42_falloc_args *args)
 {
@@ -333,6 +405,210 @@ static void encode_layouterror(struct xdr_stream *xdr,
        encode_device_error(xdr, &args->errors[0]);
 }
 
+static void encode_setxattr(struct xdr_stream *xdr,
+                           const struct nfs42_setxattrargs *arg,
+                           struct compound_hdr *hdr)
+{
+       __be32 *p;
+
+       BUILD_BUG_ON(XATTR_CREATE != SETXATTR4_CREATE);
+       BUILD_BUG_ON(XATTR_REPLACE != SETXATTR4_REPLACE);
+
+       encode_op_hdr(xdr, OP_SETXATTR, decode_setxattr_maxsz, hdr);
+       p = reserve_space(xdr, 4);
+       *p = cpu_to_be32(arg->xattr_flags);
+       encode_string(xdr, strlen(arg->xattr_name), arg->xattr_name);
+       p = reserve_space(xdr, 4);
+       *p = cpu_to_be32(arg->xattr_len);
+       if (arg->xattr_len)
+               xdr_write_pages(xdr, arg->xattr_pages, 0, arg->xattr_len);
+}
+
+static int decode_setxattr(struct xdr_stream *xdr,
+                          struct nfs4_change_info *cinfo)
+{
+       int status;
+
+       status = decode_op_hdr(xdr, OP_SETXATTR);
+       if (status)
+               goto out;
+       status = decode_change_info(xdr, cinfo);
+out:
+       return status;
+}
+
+
+static void encode_getxattr(struct xdr_stream *xdr, const char *name,
+                           struct compound_hdr *hdr)
+{
+       encode_op_hdr(xdr, OP_GETXATTR, decode_getxattr_maxsz, hdr);
+       encode_string(xdr, strlen(name), name);
+}
+
+static int decode_getxattr(struct xdr_stream *xdr,
+                          struct nfs42_getxattrres *res,
+                          struct rpc_rqst *req)
+{
+       int status;
+       __be32 *p;
+       u32 len, rdlen;
+
+       status = decode_op_hdr(xdr, OP_GETXATTR);
+       if (status)
+               return status;
+
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               return -EIO;
+
+       len = be32_to_cpup(p);
+       if (len > req->rq_rcv_buf.page_len)
+               return -ERANGE;
+
+       res->xattr_len = len;
+
+       if (len > 0) {
+               rdlen = xdr_read_pages(xdr, len);
+               if (rdlen < len)
+                       return -EIO;
+       }
+
+       return 0;
+}
+
+static void encode_removexattr(struct xdr_stream *xdr, const char *name,
+                              struct compound_hdr *hdr)
+{
+       encode_op_hdr(xdr, OP_REMOVEXATTR, decode_removexattr_maxsz, hdr);
+       encode_string(xdr, strlen(name), name);
+}
+
+
+static int decode_removexattr(struct xdr_stream *xdr,
+                          struct nfs4_change_info *cinfo)
+{
+       int status;
+
+       status = decode_op_hdr(xdr, OP_REMOVEXATTR);
+       if (status)
+               goto out;
+
+       status = decode_change_info(xdr, cinfo);
+out:
+       return status;
+}
+
+static void encode_listxattrs(struct xdr_stream *xdr,
+                            const struct nfs42_listxattrsargs *arg,
+                            struct compound_hdr *hdr)
+{
+       __be32 *p;
+
+       encode_op_hdr(xdr, OP_LISTXATTRS, decode_listxattrs_maxsz + 1, hdr);
+
+       p = reserve_space(xdr, 12);
+       if (unlikely(!p))
+               return;
+
+       p = xdr_encode_hyper(p, arg->cookie);
+       /*
+        * RFC 8276 says to specify the full max length of the LISTXATTRS
+        * XDR reply. Count is set to the XDR length of the names array
+        * plus the EOF marker. So, add the cookie and the names count.
+        */
+       *p = cpu_to_be32(arg->count + 8 + 4);
+}
+
+static int decode_listxattrs(struct xdr_stream *xdr,
+                           struct nfs42_listxattrsres *res)
+{
+       int status;
+       __be32 *p;
+       u32 count, len, ulen;
+       size_t left, copied;
+       char *buf;
+
+       status = decode_op_hdr(xdr, OP_LISTXATTRS);
+       if (status) {
+               /*
+                * Special case: for LISTXATTRS, NFS4ERR_TOOSMALL
+                * should be translated to ERANGE.
+                */
+               if (status == -ETOOSMALL)
+                       status = -ERANGE;
+               goto out;
+       }
+
+       p = xdr_inline_decode(xdr, 8);
+       if (unlikely(!p))
+               return -EIO;
+
+       xdr_decode_hyper(p, &res->cookie);
+
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               return -EIO;
+
+       left = res->xattr_len;
+       buf = res->xattr_buf;
+
+       count = be32_to_cpup(p);
+       copied = 0;
+
+       /*
+        * We have asked for enough room to encode the maximum number
+        * of possible attribute names, so everything should fit.
+        *
+        * But, don't rely on that assumption. Just decode entries
+        * until they don't fit anymore, just in case the server did
+        * something odd.
+        */
+       while (count--) {
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       return -EIO;
+
+               len = be32_to_cpup(p);
+               if (len > (XATTR_NAME_MAX - XATTR_USER_PREFIX_LEN)) {
+                       status = -ERANGE;
+                       goto out;
+               }
+
+               p = xdr_inline_decode(xdr, len);
+               if (unlikely(!p))
+                       return -EIO;
+
+               ulen = len + XATTR_USER_PREFIX_LEN + 1;
+               if (buf) {
+                       if (ulen > left) {
+                               status = -ERANGE;
+                               goto out;
+                       }
+
+                       memcpy(buf, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN);
+                       memcpy(buf + XATTR_USER_PREFIX_LEN, p, len);
+
+                       buf[ulen - 1] = 0;
+                       buf += ulen;
+                       left -= ulen;
+               }
+               copied += ulen;
+       }
+
+       p = xdr_inline_decode(xdr, 4);
+       if (unlikely(!p))
+               return -EIO;
+
+       res->eof = be32_to_cpup(p);
+       res->copied = copied;
+
+out:
+       if (status == -ERANGE && res->xattr_len == XATTR_LIST_MAX)
+               status = -E2BIG;
+
+       return status;
+}
+
 /*
  * Encode ALLOCATE request
  */
@@ -988,4 +1264,166 @@ out:
        return status;
 }
 
+#ifdef CONFIG_NFS_V4_2
+static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
+                                 const void *data)
+{
+       const struct nfs42_setxattrargs *args = data;
+       struct compound_hdr hdr = {
+               .minorversion = nfs4_xdr_minorversion(&args->seq_args),
+       };
+
+       encode_compound_hdr(xdr, req, &hdr);
+       encode_sequence(xdr, &args->seq_args, &hdr);
+       encode_putfh(xdr, args->fh, &hdr);
+       encode_setxattr(xdr, args, &hdr);
+       encode_nops(&hdr);
+}
+
+static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
+                                void *data)
+{
+       struct nfs42_setxattrres *res = data;
+       struct compound_hdr hdr;
+       int status;
+
+       status = decode_compound_hdr(xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_sequence(xdr, &res->seq_res, req);
+       if (status)
+               goto out;
+       status = decode_putfh(xdr);
+       if (status)
+               goto out;
+
+       status = decode_setxattr(xdr, &res->cinfo);
+out:
+       return status;
+}
+
+static void nfs4_xdr_enc_getxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
+                                 const void *data)
+{
+       const struct nfs42_getxattrargs *args = data;
+       struct compound_hdr hdr = {
+               .minorversion = nfs4_xdr_minorversion(&args->seq_args),
+       };
+       size_t plen;
+
+       encode_compound_hdr(xdr, req, &hdr);
+       encode_sequence(xdr, &args->seq_args, &hdr);
+       encode_putfh(xdr, args->fh, &hdr);
+       encode_getxattr(xdr, args->xattr_name, &hdr);
+
+       plen = args->xattr_len ? args->xattr_len : XATTR_SIZE_MAX;
+
+       rpc_prepare_reply_pages(req, args->xattr_pages, 0, plen,
+           hdr.replen);
+       req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
+
+       encode_nops(&hdr);
+}
+
+static int nfs4_xdr_dec_getxattr(struct rpc_rqst *rqstp,
+                                struct xdr_stream *xdr, void *data)
+{
+       struct nfs42_getxattrres *res = data;
+       struct compound_hdr hdr;
+       int status;
+
+       status = decode_compound_hdr(xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_sequence(xdr, &res->seq_res, rqstp);
+       if (status)
+               goto out;
+       status = decode_putfh(xdr);
+       if (status)
+               goto out;
+       status = decode_getxattr(xdr, res, rqstp);
+out:
+       return status;
+}
+
+static void nfs4_xdr_enc_listxattrs(struct rpc_rqst *req,
+                                   struct xdr_stream *xdr, const void *data)
+{
+       const struct nfs42_listxattrsargs *args = data;
+       struct compound_hdr hdr = {
+               .minorversion = nfs4_xdr_minorversion(&args->seq_args),
+       };
+
+       encode_compound_hdr(xdr, req, &hdr);
+       encode_sequence(xdr, &args->seq_args, &hdr);
+       encode_putfh(xdr, args->fh, &hdr);
+       encode_listxattrs(xdr, args, &hdr);
+
+       rpc_prepare_reply_pages(req, args->xattr_pages, 0, args->count,
+           hdr.replen);
+       req->rq_rcv_buf.flags |= XDRBUF_SPARSE_PAGES;
+
+       encode_nops(&hdr);
+}
+
+static int nfs4_xdr_dec_listxattrs(struct rpc_rqst *rqstp,
+                                  struct xdr_stream *xdr, void *data)
+{
+       struct nfs42_listxattrsres *res = data;
+       struct compound_hdr hdr;
+       int status;
+
+       xdr_set_scratch_buffer(xdr, page_address(res->scratch), PAGE_SIZE);
+
+       status = decode_compound_hdr(xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_sequence(xdr, &res->seq_res, rqstp);
+       if (status)
+               goto out;
+       status = decode_putfh(xdr);
+       if (status)
+               goto out;
+       status = decode_listxattrs(xdr, res);
+out:
+       return status;
+}
+
+static void nfs4_xdr_enc_removexattr(struct rpc_rqst *req,
+                                    struct xdr_stream *xdr, const void *data)
+{
+       const struct nfs42_removexattrargs *args = data;
+       struct compound_hdr hdr = {
+               .minorversion = nfs4_xdr_minorversion(&args->seq_args),
+       };
+
+       encode_compound_hdr(xdr, req, &hdr);
+       encode_sequence(xdr, &args->seq_args, &hdr);
+       encode_putfh(xdr, args->fh, &hdr);
+       encode_removexattr(xdr, args->xattr_name, &hdr);
+       encode_nops(&hdr);
+}
+
+static int nfs4_xdr_dec_removexattr(struct rpc_rqst *req,
+                                   struct xdr_stream *xdr, void *data)
+{
+       struct nfs42_removexattrres *res = data;
+       struct compound_hdr hdr;
+       int status;
+
+       status = decode_compound_hdr(xdr, &hdr);
+       if (status)
+               goto out;
+       status = decode_sequence(xdr, &res->seq_res, req);
+       if (status)
+               goto out;
+       status = decode_putfh(xdr);
+       if (status)
+               goto out;
+
+       status = decode_removexattr(xdr, &res->cinfo);
+out:
+       return status;
+}
+#endif
 #endif /* __LINUX_FS_NFS_NFS4_2XDR_H */
index 210e590..0c9505d 100644 (file)
@@ -324,6 +324,13 @@ extern int update_open_stateid(struct nfs4_state *state,
 
 extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
                struct nfs_fsinfo *fsinfo);
+extern void nfs4_update_changeattr(struct inode *dir,
+                                  struct nfs4_change_info *cinfo,
+                                  unsigned long timestamp,
+                                  unsigned long cache_validity);
+extern int nfs4_buf_to_pages_noslab(const void *buf, size_t buflen,
+                                   struct page **pages);
+
 #if defined(CONFIG_NFS_V4_1)
 extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res *);
 extern int nfs4_proc_create_session(struct nfs_client *, const struct cred *);
@@ -557,6 +564,12 @@ static inline void nfs4_unregister_sysctl(void)
 /* nfs4xdr.c */
 extern const struct rpc_procinfo nfs4_procedures[];
 
+#ifdef CONFIG_NFS_V4_2
+extern const u32 nfs42_maxsetxattr_overhead;
+extern const u32 nfs42_maxgetxattr_overhead;
+extern const u32 nfs42_maxlistxattrs_overhead;
+#endif
+
 struct nfs4_mount_data;
 
 /* callback_xdr.c */
@@ -613,12 +626,34 @@ static inline bool nfs4_state_match_open_stateid_other(const struct nfs4_state *
                nfs4_stateid_match_other(&state->open_stateid, stateid);
 }
 
+/* nfs42xattr.c */
+#ifdef CONFIG_NFS_V4_2
+extern int __init nfs4_xattr_cache_init(void);
+extern void nfs4_xattr_cache_exit(void);
+extern void nfs4_xattr_cache_add(struct inode *inode, const char *name,
+                                const char *buf, struct page **pages,
+                                ssize_t buflen);
+extern void nfs4_xattr_cache_remove(struct inode *inode, const char *name);
+extern ssize_t nfs4_xattr_cache_get(struct inode *inode, const char *name,
+                               char *buf, ssize_t buflen);
+extern void nfs4_xattr_cache_set_list(struct inode *inode, const char *buf,
+                                     ssize_t buflen);
+extern ssize_t nfs4_xattr_cache_list(struct inode *inode, char *buf,
+                                    ssize_t buflen);
+extern void nfs4_xattr_cache_zap(struct inode *inode);
 #else
+static inline void nfs4_xattr_cache_zap(struct inode *inode)
+{
+}
+#endif /* CONFIG_NFS_V4_2 */
+
+#else /* CONFIG_NFS_V4 */
 
 #define nfs4_close_state(a, b) do { } while (0)
 #define nfs4_close_sync(a, b) do { } while (0)
 #define nfs4_state_protect(a, b, c, d) do { } while (0)
 #define nfs4_state_protect_write(a, b, c, d) do { } while (0)
 
+
 #endif /* CONFIG_NFS_V4 */
 #endif /* __LINUX_FS_NFS_NFS4_FS.H */
index 0bd77cc..daacc78 100644 (file)
@@ -880,7 +880,7 @@ static int nfs4_set_client(struct nfs_server *server,
 
        if (minorversion == 0)
                __set_bit(NFS_CS_REUSEPORT, &cl_init.init_flags);
-       else if (proto == XPRT_TRANSPORT_TCP)
+       if (proto == XPRT_TRANSPORT_TCP)
                cl_init.nconnect = nconnect;
 
        if (server->flags & NFS_MOUNT_NORESVPORT)
@@ -992,6 +992,36 @@ static void nfs4_session_limit_rwsize(struct nfs_server *server)
 #endif /* CONFIG_NFS_V4_1 */
 }
 
+/*
+ * Limit xattr sizes using the channel attributes.
+ */
+static void nfs4_session_limit_xasize(struct nfs_server *server)
+{
+#ifdef CONFIG_NFS_V4_2
+       struct nfs4_session *sess;
+       u32 server_gxa_sz;
+       u32 server_sxa_sz;
+       u32 server_lxa_sz;
+
+       if (!nfs4_has_session(server->nfs_client))
+               return;
+
+       sess = server->nfs_client->cl_session;
+
+       server_gxa_sz = sess->fc_attrs.max_resp_sz - nfs42_maxgetxattr_overhead;
+       server_sxa_sz = sess->fc_attrs.max_rqst_sz - nfs42_maxsetxattr_overhead;
+       server_lxa_sz = sess->fc_attrs.max_resp_sz -
+           nfs42_maxlistxattrs_overhead;
+
+       if (server->gxasize > server_gxa_sz)
+               server->gxasize = server_gxa_sz;
+       if (server->sxasize > server_sxa_sz)
+               server->sxasize = server_sxa_sz;
+       if (server->lxasize > server_lxa_sz)
+               server->lxasize = server_lxa_sz;
+#endif
+}
+
 static int nfs4_server_common_setup(struct nfs_server *server,
                struct nfs_fh *mntfh, bool auth_probe)
 {
@@ -1039,6 +1069,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
                goto out;
 
        nfs4_session_limit_rwsize(server);
+       nfs4_session_limit_xasize(server);
 
        if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN)
                server->namelen = NFS4_MAXNAMLEN;
index 8e5d622..a339707 100644 (file)
@@ -110,6 +110,7 @@ static int
 nfs4_file_flush(struct file *file, fl_owner_t id)
 {
        struct inode    *inode = file_inode(file);
+       errseq_t since;
 
        dprintk("NFS: flush(%pD2)\n", file);
 
@@ -125,7 +126,9 @@ nfs4_file_flush(struct file *file, fl_owner_t id)
                return filemap_fdatawrite(file->f_mapping);
 
        /* Flush writes to the server and return any errors */
-       return nfs_wb_all(inode);
+       since = filemap_sample_wb_err(file->f_mapping);
+       nfs_wb_all(inode);
+       return filemap_check_wb_err(file->f_mapping, since);
 }
 
 #ifdef CONFIG_NFS_V4_2
index 8963062..dbd0154 100644 (file)
@@ -66,6 +66,7 @@
 #include "nfs4idmap.h"
 #include "nfs4session.h"
 #include "fscache.h"
+#include "nfs42.h"
 
 #include "nfs4trace.h"
 
@@ -256,6 +257,7 @@ const u32 nfs4_fsinfo_bitmap[3] = { FATTR4_WORD0_MAXFILESIZE
                        | FATTR4_WORD1_FS_LAYOUT_TYPES,
                        FATTR4_WORD2_LAYOUT_BLKSIZE
                        | FATTR4_WORD2_CLONE_BLKSIZE
+                       | FATTR4_WORD2_XATTR_SUPPORT
 };
 
 const u32 nfs4_fs_locations_bitmap[3] = {
@@ -1173,37 +1175,49 @@ nfs4_dec_nlink_locked(struct inode *inode)
 }
 
 static void
-update_changeattr_locked(struct inode *dir, struct nfs4_change_info *cinfo,
+nfs4_update_changeattr_locked(struct inode *inode,
+               struct nfs4_change_info *cinfo,
                unsigned long timestamp, unsigned long cache_validity)
 {
-       struct nfs_inode *nfsi = NFS_I(dir);
+       struct nfs_inode *nfsi = NFS_I(inode);
 
        nfsi->cache_validity |= NFS_INO_INVALID_CTIME
                | NFS_INO_INVALID_MTIME
-               | NFS_INO_INVALID_DATA
                | cache_validity;
-       if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(dir)) {
+
+       if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) {
                nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
                nfsi->attrtimeo_timestamp = jiffies;
        } else {
-               nfs_force_lookup_revalidate(dir);
-               if (cinfo->before != inode_peek_iversion_raw(dir))
+               if (S_ISDIR(inode->i_mode)) {
+                       nfsi->cache_validity |= NFS_INO_INVALID_DATA;
+                       nfs_force_lookup_revalidate(inode);
+               } else {
+                       if (!NFS_PROTO(inode)->have_delegation(inode,
+                                                              FMODE_READ))
+                               nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
+               }
+
+               if (cinfo->before != inode_peek_iversion_raw(inode))
                        nfsi->cache_validity |= NFS_INO_INVALID_ACCESS |
-                               NFS_INO_INVALID_ACL;
+                                               NFS_INO_INVALID_ACL |
+                                               NFS_INO_INVALID_XATTR;
        }
-       inode_set_iversion_raw(dir, cinfo->after);
+       inode_set_iversion_raw(inode, cinfo->after);
        nfsi->read_cache_jiffies = timestamp;
        nfsi->attr_gencount = nfs_inc_attr_generation_counter();
        nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE;
-       nfs_fscache_invalidate(dir);
+
+       if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
+               nfs_fscache_invalidate(inode);
 }
 
-static void
-update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
+void
+nfs4_update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
                unsigned long timestamp, unsigned long cache_validity)
 {
        spin_lock(&dir->i_lock);
-       update_changeattr_locked(dir, cinfo, timestamp, cache_validity);
+       nfs4_update_changeattr_locked(dir, cinfo, timestamp, cache_validity);
        spin_unlock(&dir->i_lock);
 }
 
@@ -1356,6 +1370,12 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct dentry *dentry,
                                NFS4_ACCESS_MODIFY |
                                NFS4_ACCESS_EXTEND |
                                NFS4_ACCESS_EXECUTE;
+#ifdef CONFIG_NFS_V4_2
+                       if (server->caps & NFS_CAP_XATTR)
+                               p->o_arg.access |= NFS4_ACCESS_XAREAD |
+                                   NFS4_ACCESS_XAWRITE |
+                                   NFS4_ACCESS_XALIST;
+#endif
                }
        }
        p->o_arg.clientid = server->nfs_client->cl_clientid;
@@ -2653,8 +2673,9 @@ static int _nfs4_proc_open(struct nfs4_opendata *data,
                        data->file_created = true;
                if (data->file_created ||
                    inode_peek_iversion_raw(dir) != o_res->cinfo.after)
-                       update_changeattr(dir, &o_res->cinfo,
-                                       o_res->f_attr->time_start, 0);
+                       nfs4_update_changeattr(dir, &o_res->cinfo,
+                                       o_res->f_attr->time_start,
+                                       NFS_INO_INVALID_DATA);
        }
        if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
                server->caps &= ~NFS_CAP_POSIX_LOCK;
@@ -3756,7 +3777,7 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
 
 #define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
 #define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL)
-#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_MODE_UMASK - 1UL)
+#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_XATTR_SUPPORT - 1UL)
 
 static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
 {
@@ -4540,7 +4561,8 @@ _nfs4_proc_remove(struct inode *dir, const struct qstr *name, u32 ftype)
        status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
        if (status == 0) {
                spin_lock(&dir->i_lock);
-               update_changeattr_locked(dir, &res.cinfo, timestamp, 0);
+               nfs4_update_changeattr_locked(dir, &res.cinfo, timestamp,
+                                             NFS_INO_INVALID_DATA);
                /* Removing a directory decrements nlink in the parent */
                if (ftype == NF4DIR && dir->i_nlink > 2)
                        nfs4_dec_nlink_locked(dir);
@@ -4624,8 +4646,9 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
                                    &data->timeout) == -EAGAIN)
                return 0;
        if (task->tk_status == 0)
-               update_changeattr(dir, &res->cinfo,
-                               res->dir_attr->time_start, 0);
+               nfs4_update_changeattr(dir, &res->cinfo,
+                               res->dir_attr->time_start,
+                               NFS_INO_INVALID_DATA);
        return 1;
 }
 
@@ -4669,16 +4692,18 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
        if (task->tk_status == 0) {
                if (new_dir != old_dir) {
                        /* Note: If we moved a directory, nlink will change */
-                       update_changeattr(old_dir, &res->old_cinfo,
+                       nfs4_update_changeattr(old_dir, &res->old_cinfo,
                                        res->old_fattr->time_start,
-                                       NFS_INO_INVALID_OTHER);
-                       update_changeattr(new_dir, &res->new_cinfo,
+                                       NFS_INO_INVALID_OTHER |
+                                           NFS_INO_INVALID_DATA);
+                       nfs4_update_changeattr(new_dir, &res->new_cinfo,
                                        res->new_fattr->time_start,
-                                       NFS_INO_INVALID_OTHER);
+                                       NFS_INO_INVALID_OTHER |
+                                           NFS_INO_INVALID_DATA);
                } else
-                       update_changeattr(old_dir, &res->old_cinfo,
+                       nfs4_update_changeattr(old_dir, &res->old_cinfo,
                                        res->old_fattr->time_start,
-                                       0);
+                                       NFS_INO_INVALID_DATA);
        }
        return 1;
 }
@@ -4719,7 +4744,8 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
 
        status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
        if (!status) {
-               update_changeattr(dir, &res.cinfo, res.fattr->time_start, 0);
+               nfs4_update_changeattr(dir, &res.cinfo, res.fattr->time_start,
+                                      NFS_INO_INVALID_DATA);
                status = nfs_post_op_update_inode(inode, res.fattr);
                if (!status)
                        nfs_setsecurity(inode, res.fattr, res.label);
@@ -4797,8 +4823,9 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
                                    &data->arg.seq_args, &data->res.seq_res, 1);
        if (status == 0) {
                spin_lock(&dir->i_lock);
-               update_changeattr_locked(dir, &data->res.dir_cinfo,
-                               data->res.fattr->time_start, 0);
+               nfs4_update_changeattr_locked(dir, &data->res.dir_cinfo,
+                               data->res.fattr->time_start,
+                               NFS_INO_INVALID_DATA);
                /* Creating a directory bumps nlink in the parent */
                if (data->arg.ftype == NF4DIR)
                        nfs4_inc_nlink_locked(dir);
@@ -5531,7 +5558,7 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server)
  */
 #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)
 
-static int buf_to_pages_noslab(const void *buf, size_t buflen,
+int nfs4_buf_to_pages_noslab(const void *buf, size_t buflen,
                struct page **pages)
 {
        struct page *newpage, **spages;
@@ -5773,7 +5800,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
                return -EOPNOTSUPP;
        if (npages > ARRAY_SIZE(pages))
                return -ERANGE;
-       i = buf_to_pages_noslab(buf, buflen, arg.acl_pages);
+       i = nfs4_buf_to_pages_noslab(buf, buflen, arg.acl_pages);
        if (i < 0)
                return i;
        nfs4_inode_make_writeable(inode);
@@ -5845,8 +5872,6 @@ static int _nfs4_get_security_label(struct inode *inode, void *buf,
                return ret;
        if (!(fattr.valid & NFS_ATTR_FATTR_V4_SECURITY_LABEL))
                return -ENOENT;
-       if (buflen < label.len)
-               return -ERANGE;
        return 0;
 }
 
@@ -7430,6 +7455,133 @@ nfs4_listxattr_nfs4_label(struct inode *inode, char *list, size_t list_len)
 
 #endif
 
+#ifdef CONFIG_NFS_V4_2
+static int nfs4_xattr_set_nfs4_user(const struct xattr_handler *handler,
+                                   struct dentry *unused, struct inode *inode,
+                                   const char *key, const void *buf,
+                                   size_t buflen, int flags)
+{
+       struct nfs_access_entry cache;
+       int ret;
+
+       if (!nfs_server_capable(inode, NFS_CAP_XATTR))
+               return -EOPNOTSUPP;
+
+       /*
+        * There is no mapping from the MAY_* flags to the NFS_ACCESS_XA*
+        * flags right now. Handling of xattr operations use the normal
+        * file read/write permissions.
+        *
+        * Just in case the server has other ideas (which RFC 8276 allows),
+        * do a cached access check for the XA* flags to possibly avoid
+        * doing an RPC and getting EACCES back.
+        */
+       if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
+               if (!(cache.mask & NFS_ACCESS_XAWRITE))
+                       return -EACCES;
+       }
+
+       if (buf == NULL) {
+               ret = nfs42_proc_removexattr(inode, key);
+               if (!ret)
+                       nfs4_xattr_cache_remove(inode, key);
+       } else {
+               ret = nfs42_proc_setxattr(inode, key, buf, buflen, flags);
+               if (!ret)
+                       nfs4_xattr_cache_add(inode, key, buf, NULL, buflen);
+       }
+
+       return ret;
+}
+
+static int nfs4_xattr_get_nfs4_user(const struct xattr_handler *handler,
+                                   struct dentry *unused, struct inode *inode,
+                                   const char *key, void *buf, size_t buflen)
+{
+       struct nfs_access_entry cache;
+       ssize_t ret;
+
+       if (!nfs_server_capable(inode, NFS_CAP_XATTR))
+               return -EOPNOTSUPP;
+
+       if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
+               if (!(cache.mask & NFS_ACCESS_XAREAD))
+                       return -EACCES;
+       }
+
+       ret = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+       if (ret)
+               return ret;
+
+       ret = nfs4_xattr_cache_get(inode, key, buf, buflen);
+       if (ret >= 0 || (ret < 0 && ret != -ENOENT))
+               return ret;
+
+       ret = nfs42_proc_getxattr(inode, key, buf, buflen);
+
+       return ret;
+}
+
+static ssize_t
+nfs4_listxattr_nfs4_user(struct inode *inode, char *list, size_t list_len)
+{
+       u64 cookie;
+       bool eof;
+       ssize_t ret, size;
+       char *buf;
+       size_t buflen;
+       struct nfs_access_entry cache;
+
+       if (!nfs_server_capable(inode, NFS_CAP_XATTR))
+               return 0;
+
+       if (!nfs_access_get_cached(inode, current_cred(), &cache, true)) {
+               if (!(cache.mask & NFS_ACCESS_XALIST))
+                       return 0;
+       }
+
+       ret = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+       if (ret)
+               return ret;
+
+       ret = nfs4_xattr_cache_list(inode, list, list_len);
+       if (ret >= 0 || (ret < 0 && ret != -ENOENT))
+               return ret;
+
+       cookie = 0;
+       eof = false;
+       buflen = list_len ? list_len : XATTR_LIST_MAX;
+       buf = list_len ? list : NULL;
+       size = 0;
+
+       while (!eof) {
+               ret = nfs42_proc_listxattrs(inode, buf, buflen,
+                   &cookie, &eof);
+               if (ret < 0)
+                       return ret;
+
+               if (list_len) {
+                       buf += ret;
+                       buflen -= ret;
+               }
+               size += ret;
+       }
+
+       if (list_len)
+               nfs4_xattr_cache_set_list(inode, list, size);
+
+       return size;
+}
+
+#else
+
+static ssize_t
+nfs4_listxattr_nfs4_user(struct inode *inode, char *list, size_t list_len)
+{
+       return 0;
+}
+#endif /* CONFIG_NFS_V4_2 */
+
 /*
  * nfs_fhget will use either the mounted_on_fileid or the fileid
  */
@@ -10035,7 +10187,7 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
 
 static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
 {
-       ssize_t error, error2;
+       ssize_t error, error2, error3;
 
        error = generic_listxattr(dentry, list, size);
        if (error < 0)
@@ -10048,7 +10200,17 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size)
        error2 = nfs4_listxattr_nfs4_label(d_inode(dentry), list, size);
        if (error2 < 0)
                return error2;
-       return error + error2;
+
+       if (list) {
+               list += error2;
+               size -= error2;
+       }
+
+       error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, size);
+       if (error3 < 0)
+               return error3;
+
+       return error + error2 + error3;
 }
 
 static const struct inode_operations nfs4_dir_inode_operations = {
@@ -10136,10 +10298,21 @@ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
        .set    = nfs4_xattr_set_nfs4_acl,
 };
 
+#ifdef CONFIG_NFS_V4_2
+static const struct xattr_handler nfs4_xattr_nfs4_user_handler = {
+       .prefix = XATTR_USER_PREFIX,
+       .get    = nfs4_xattr_get_nfs4_user,
+       .set    = nfs4_xattr_set_nfs4_user,
+};
+#endif
+
 const struct xattr_handler *nfs4_xattr_handlers[] = {
        &nfs4_xattr_nfs4_acl_handler,
 #ifdef CONFIG_NFS_V4_SECURITY_LABEL
        &nfs4_xattr_nfs4_label_handler,
+#endif
+#ifdef CONFIG_NFS_V4_2
+       &nfs4_xattr_nfs4_user_handler,
 #endif
        NULL
 };
index 1475f93..0c1ab84 100644 (file)
@@ -69,6 +69,7 @@ static void nfs4_evict_inode(struct inode *inode)
        pnfs_destroy_layout(NFS_I(inode));
        /* First call standard NFS clear_inode() code */
        nfs_clear_inode(inode);
+       nfs4_xattr_cache_zap(inode);
 }
 
 struct nfs_referral_count {
@@ -268,6 +269,12 @@ static int __init init_nfs_v4(void)
        if (err)
                goto out1;
 
+#ifdef CONFIG_NFS_V4_2
+       err = nfs4_xattr_cache_init();
+       if (err)
+               goto out2;
+#endif
+
        err = nfs4_register_sysctl();
        if (err)
                goto out2;
@@ -288,6 +295,9 @@ static void __exit exit_nfs_v4(void)
        nfs4_pnfs_v3_ds_connect_unload();
 
        unregister_nfs_version(&nfs_v4);
+#ifdef CONFIG_NFS_V4_2
+       nfs4_xattr_cache_exit();
+#endif
        nfs4_unregister_sysctl();
        nfs_idmap_quit();
        nfs_dns_resolver_destroy();
index 5435411..b4f852d 100644 (file)
@@ -1727,6 +1727,13 @@ DEFINE_NFS4_IDMAP_EVENT(nfs4_map_group_to_gid);
 DEFINE_NFS4_IDMAP_EVENT(nfs4_map_uid_to_name);
 DEFINE_NFS4_IDMAP_EVENT(nfs4_map_gid_to_group);
 
+#ifdef CONFIG_NFS_V4_1
+#define NFS4_LSEG_LAYOUT_STATEID_HASH(lseg) \
+       (lseg ? nfs_stateid_hash(&lseg->pls_layout->plh_stateid) : 0)
+#else
+#define NFS4_LSEG_LAYOUT_STATEID_HASH(lseg) (0)
+#endif
+
 DECLARE_EVENT_CLASS(nfs4_read_event,
                TP_PROTO(
                        const struct nfs_pgio_header *hdr,
@@ -1745,6 +1752,8 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
                        __field(unsigned long, error)
                        __field(int, stateid_seq)
                        __field(u32, stateid_hash)
+                       __field(int, layoutstateid_seq)
+                       __field(u32, layoutstateid_hash)
                ),
 
                TP_fast_assign(
@@ -1754,6 +1763,7 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
                                                  hdr->args.fh : &nfsi->fh;
                        const struct nfs4_state *state =
                                hdr->args.context->state;
+                       const struct pnfs_layout_segment *lseg = hdr->lseg;
 
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
@@ -1766,11 +1776,15 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
                                be32_to_cpu(state->stateid.seqid);
                        __entry->stateid_hash =
                                nfs_stateid_hash(&state->stateid);
+                       __entry->layoutstateid_seq = lseg ? lseg->pls_seq : 0;
+                       __entry->layoutstateid_hash =
+                               NFS4_LSEG_LAYOUT_STATEID_HASH(lseg);
                ),
 
                TP_printk(
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%u res=%u stateid=%d:0x%08x",
+                       "offset=%lld count=%u res=%u stateid=%d:0x%08x "
+                       "layoutstateid=%d:0x%08x",
                        -__entry->error,
                        show_nfsv4_errors(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -1778,7 +1792,8 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
                        __entry->fhandle,
                        (long long)__entry->offset,
                        __entry->arg_count, __entry->res_count,
-                       __entry->stateid_seq, __entry->stateid_hash
+                       __entry->stateid_seq, __entry->stateid_hash,
+                       __entry->layoutstateid_seq, __entry->layoutstateid_hash
                )
 );
 #define DEFINE_NFS4_READ_EVENT(name) \
@@ -1811,6 +1826,8 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
                        __field(unsigned long, error)
                        __field(int, stateid_seq)
                        __field(u32, stateid_hash)
+                       __field(int, layoutstateid_seq)
+                       __field(u32, layoutstateid_hash)
                ),
 
                TP_fast_assign(
@@ -1820,6 +1837,7 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
                                                  hdr->args.fh : &nfsi->fh;
                        const struct nfs4_state *state =
                                hdr->args.context->state;
+                       const struct pnfs_layout_segment *lseg = hdr->lseg;
 
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
@@ -1832,11 +1850,15 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
                                be32_to_cpu(state->stateid.seqid);
                        __entry->stateid_hash =
                                nfs_stateid_hash(&state->stateid);
+                       __entry->layoutstateid_seq = lseg ? lseg->pls_seq : 0;
+                       __entry->layoutstateid_hash =
+                               NFS4_LSEG_LAYOUT_STATEID_HASH(lseg);
                ),
 
                TP_printk(
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%u res=%u stateid=%d:0x%08x",
+                       "offset=%lld count=%u res=%u stateid=%d:0x%08x "
+                       "layoutstateid=%d:0x%08x",
                        -__entry->error,
                        show_nfsv4_errors(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -1844,7 +1866,8 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
                        __entry->fhandle,
                        (long long)__entry->offset,
                        __entry->arg_count, __entry->res_count,
-                       __entry->stateid_seq, __entry->stateid_hash
+                       __entry->stateid_seq, __entry->stateid_hash,
+                       __entry->layoutstateid_seq, __entry->layoutstateid_hash
                )
 );
 
@@ -1875,6 +1898,8 @@ DECLARE_EVENT_CLASS(nfs4_commit_event,
                        __field(unsigned long, error)
                        __field(loff_t, offset)
                        __field(u32, count)
+                       __field(int, layoutstateid_seq)
+                       __field(u32, layoutstateid_hash)
                ),
 
                TP_fast_assign(
@@ -1882,6 +1907,7 @@ DECLARE_EVENT_CLASS(nfs4_commit_event,
                        const struct nfs_inode *nfsi = NFS_I(inode);
                        const struct nfs_fh *fh = data->args.fh ?
                                                  data->args.fh : &nfsi->fh;
+                       const struct pnfs_layout_segment *lseg = data->lseg;
 
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
@@ -1889,18 +1915,22 @@ DECLARE_EVENT_CLASS(nfs4_commit_event,
                        __entry->offset = data->args.offset;
                        __entry->count = data->args.count;
                        __entry->error = error < 0 ? -error : 0;
+                       __entry->layoutstateid_seq = lseg ? lseg->pls_seq : 0;
+                       __entry->layoutstateid_hash =
+                               NFS4_LSEG_LAYOUT_STATEID_HASH(lseg);
                ),
 
                TP_printk(
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%u",
+                       "offset=%lld count=%u layoutstateid=%d:0x%08x",
                        -__entry->error,
                        show_nfsv4_errors(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
                        (long long)__entry->offset,
-                       __entry->count
+                       __entry->count,
+                       __entry->layoutstateid_seq, __entry->layoutstateid_hash
                )
 );
 #define DEFINE_NFS4_COMMIT_EVENT(name) \
@@ -1993,7 +2023,9 @@ TRACE_EVENT(nfs4_layoutget,
 
 DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutcommit);
 DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutreturn);
-DEFINE_NFS4_INODE_EVENT(nfs4_layoutreturn_on_close);
+DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutreturn_on_close);
+DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layouterror);
+DEFINE_NFS4_INODE_STATEID_EVENT(nfs4_layoutstats);
 
 TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_UNKNOWN);
 TRACE_DEFINE_ENUM(PNFS_UPDATE_LAYOUT_NO_PNFS);
index 47817ef..0b3510f 100644 (file)
@@ -4166,7 +4166,11 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap,
                        return -EIO;
                if (len < NFS4_MAXLABELLEN) {
                        if (label) {
-                               memcpy(label->label, p, len);
+                               if (label->len) {
+                                       if (label->len < len)
+                                               return -ERANGE;
+                                       memcpy(label->label, p, len);
+                               }
                                label->len = len;
                                label->pi = pi;
                                label->lfs = lfs;
@@ -4201,6 +4205,26 @@ static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, str
        return status;
 }
 
+static int decode_attr_xattrsupport(struct xdr_stream *xdr, uint32_t *bitmap,
+                                   uint32_t *res)
+{
+       __be32 *p;
+
+       *res = 0;
+       if (unlikely(bitmap[2] & (FATTR4_WORD2_XATTR_SUPPORT - 1U)))
+               return -EIO;
+       if (likely(bitmap[2] & FATTR4_WORD2_XATTR_SUPPORT)) {
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       return -EIO;
+               *res = be32_to_cpup(p);
+               bitmap[2] &= ~FATTR4_WORD2_XATTR_SUPPORT;
+       }
+       dprintk("%s: XATTR support=%s\n", __func__,
+               *res == 0 ? "false" : "true");
+       return 0;
+}
+
 static int verify_attr_len(struct xdr_stream *xdr, unsigned int savep, uint32_t attrlen)
 {
        unsigned int attrwords = XDR_QUADLEN(attrlen);
@@ -4855,6 +4879,11 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
        if (status)
                goto xdr_error;
 
+       status = decode_attr_xattrsupport(xdr, bitmap,
+                                         &fsinfo->xattr_support);
+       if (status)
+               goto xdr_error;
+
        status = verify_attr_len(xdr, savep, attrlen);
 xdr_error:
        dprintk("%s: xdr returned %d!\n", __func__, -status);
@@ -5227,7 +5256,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
         * The XDR encode routine has set things up so that
         * the link text will be copied directly into the
         * buffer.  We just have to do overflow-checking,
-        * and and null-terminate the text (the VFS expects
+        * and null-terminate the text (the VFS expects
         * null-termination).
         */
        xdr_terminate_string(rcvbuf, len);
@@ -7456,6 +7485,8 @@ static struct {
        { NFS4ERR_SYMLINK,      -ELOOP          },
        { NFS4ERR_OP_ILLEGAL,   -EOPNOTSUPP     },
        { NFS4ERR_DEADLOCK,     -EDEADLK        },
+       { NFS4ERR_NOXATTR,      -ENODATA        },
+       { NFS4ERR_XATTR2BIG,    -E2BIG          },
        { -1,                   -EIO            }
 };
 
@@ -7584,6 +7615,10 @@ const struct rpc_procinfo nfs4_procedures[] = {
        PROC42(COPY_NOTIFY,     enc_copy_notify,        dec_copy_notify),
        PROC(LOOKUPP,           enc_lookupp,            dec_lookupp),
        PROC42(LAYOUTERROR,     enc_layouterror,        dec_layouterror),
+       PROC42(GETXATTR,        enc_getxattr,           dec_getxattr),
+       PROC42(SETXATTR,        enc_setxattr,           dec_setxattr),
+       PROC42(LISTXATTRS,      enc_listxattrs,         dec_listxattrs),
+       PROC42(REMOVEXATTR,     enc_removexattr,        dec_removexattr),
 };
 
 static unsigned int nfs_version4_counts[ARRAY_SIZE(nfs4_procedures)];
index 547cec7..5a59dcd 100644 (file)
@@ -59,7 +59,8 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_OTHER);
                        { NFS_INO_INVALID_CTIME, "INVALID_CTIME" }, \
                        { NFS_INO_INVALID_MTIME, "INVALID_MTIME" }, \
                        { NFS_INO_INVALID_SIZE, "INVALID_SIZE" }, \
-                       { NFS_INO_INVALID_OTHER, "INVALID_OTHER" })
+                       { NFS_INO_INVALID_OTHER, "INVALID_OTHER" }, \
+                       { NFS_INO_INVALID_XATTR, "INVALID_XATTR" })
 
 TRACE_DEFINE_ENUM(NFS_INO_ADVISE_RDPLUS);
 TRACE_DEFINE_ENUM(NFS_INO_STALE);
index dd2e14f..40332c7 100644 (file)
@@ -1226,31 +1226,27 @@ out:
        return status;
 }
 
+static bool
+pnfs_layout_segments_returnable(struct pnfs_layout_hdr *lo,
+                               enum pnfs_iomode iomode,
+                               u32 seq)
+{
+       struct pnfs_layout_range recall_range = {
+               .length = NFS4_MAX_UINT64,
+               .iomode = iomode,
+       };
+       return pnfs_mark_matching_lsegs_return(lo, &lo->plh_return_segs,
+                                              &recall_range, seq) != -EBUSY;
+}
+
 /* Return true if layoutreturn is needed */
 static bool
 pnfs_layout_need_return(struct pnfs_layout_hdr *lo)
 {
-       struct pnfs_layout_segment *s;
-       enum pnfs_iomode iomode;
-       u32 seq;
-
        if (!test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags))
                return false;
-
-       seq = lo->plh_return_seq;
-       iomode = lo->plh_return_iomode;
-
-       /* Defer layoutreturn until all recalled lsegs are done */
-       list_for_each_entry(s, &lo->plh_segs, pls_list) {
-               if (seq && pnfs_seqid_is_newer(s->pls_seq, seq))
-                       continue;
-               if (iomode != IOMODE_ANY && s->pls_range.iomode != iomode)
-                       continue;
-               if (test_bit(NFS_LSEG_LAYOUTRETURN, &s->pls_flags))
-                       return false;
-       }
-
-       return true;
+       return pnfs_layout_segments_returnable(lo, lo->plh_return_iomode,
+                                              lo->plh_return_seq);
 }
 
 static void pnfs_layoutreturn_before_put_layout_hdr(struct pnfs_layout_hdr *lo)
@@ -1549,12 +1545,12 @@ void pnfs_roc_release(struct nfs4_layoutreturn_args *args,
        default:
                arg_stateid = &args->stateid;
        }
+       trace_nfs4_layoutreturn_on_close(args->inode, &args->stateid, ret);
        pnfs_layoutreturn_free_lsegs(lo, arg_stateid, &args->range,
                        res_stateid);
        if (ld_private && ld_private->ops && ld_private->ops->free)
                ld_private->ops->free(ld_private);
        pnfs_put_layout_hdr(lo);
-       trace_nfs4_layoutreturn_on_close(args->inode, 0);
 }
 
 bool pnfs_wait_on_layoutreturn(struct inode *ino, struct rpc_task *task)
@@ -2392,16 +2388,6 @@ out_forget:
        return ERR_PTR(-EAGAIN);
 }
 
-static int
-mark_lseg_invalid_or_return(struct pnfs_layout_segment *lseg,
-               struct list_head *tmp_list)
-{
-       if (!mark_lseg_invalid(lseg, tmp_list))
-               return 0;
-       pnfs_cache_lseg_for_layoutreturn(lseg->pls_layout, lseg);
-       return 1;
-}
-
 /**
  * pnfs_mark_matching_lsegs_return - Free or return matching layout segments
  * @lo: pointer to layout header
@@ -2438,7 +2424,7 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo,
                                lseg, lseg->pls_range.iomode,
                                lseg->pls_range.offset,
                                lseg->pls_range.length);
-                       if (mark_lseg_invalid_or_return(lseg, tmp_list))
+                       if (mark_lseg_invalid(lseg, tmp_list))
                                continue;
                        remaining++;
                        set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags);
@@ -2953,7 +2939,8 @@ pnfs_try_to_read_data(struct nfs_pgio_header *hdr,
 }
 
 /* Resend all requests through pnfs. */
-void pnfs_read_resend_pnfs(struct nfs_pgio_header *hdr)
+void pnfs_read_resend_pnfs(struct nfs_pgio_header *hdr,
+                          unsigned int mirror_idx)
 {
        struct nfs_pageio_descriptor pgio;
 
@@ -2964,6 +2951,7 @@ void pnfs_read_resend_pnfs(struct nfs_pgio_header *hdr)
 
                nfs_pageio_init_read(&pgio, hdr->inode, false,
                                        hdr->completion_ops);
+               pgio.pg_mirror_idx = mirror_idx;
                hdr->task.tk_status = nfs_pageio_resend(&pgio, hdr);
        }
 }
index 8e0ada5..2661c44 100644 (file)
@@ -311,7 +311,7 @@ int _pnfs_return_layout(struct inode *);
 int pnfs_commit_and_return_layout(struct inode *);
 void pnfs_ld_write_done(struct nfs_pgio_header *);
 void pnfs_ld_read_done(struct nfs_pgio_header *);
-void pnfs_read_resend_pnfs(struct nfs_pgio_header *);
+void pnfs_read_resend_pnfs(struct nfs_pgio_header *, unsigned int mirror_idx);
 struct pnfs_layout_segment *pnfs_update_layout(struct inode *ino,
                                               struct nfs_open_context *ctx,
                                               loff_t pos,
index 30a3aab..dabf8cb 100644 (file)
@@ -163,7 +163,7 @@ static inline u16 readw(const volatile void __iomem *addr)
        u16 val;
 
        __io_br();
-       val = __le16_to_cpu(__raw_readw(addr));
+       val = __le16_to_cpu((__le16 __force)__raw_readw(addr));
        __io_ar(val);
        return val;
 }
@@ -176,7 +176,7 @@ static inline u32 readl(const volatile void __iomem *addr)
        u32 val;
 
        __io_br();
-       val = __le32_to_cpu(__raw_readl(addr));
+       val = __le32_to_cpu((__le32 __force)__raw_readl(addr));
        __io_ar(val);
        return val;
 }
@@ -212,7 +212,7 @@ static inline void writeb(u8 value, volatile void __iomem *addr)
 static inline void writew(u16 value, volatile void __iomem *addr)
 {
        __io_bw();
-       __raw_writew(cpu_to_le16(value), addr);
+       __raw_writew((u16 __force)cpu_to_le16(value), addr);
        __io_aw();
 }
 #endif
@@ -222,7 +222,7 @@ static inline void writew(u16 value, volatile void __iomem *addr)
 static inline void writel(u32 value, volatile void __iomem *addr)
 {
        __io_bw();
-       __raw_writel(__cpu_to_le32(value), addr);
+       __raw_writel((u32 __force)__cpu_to_le32(value), addr);
        __io_aw();
 }
 #endif
@@ -474,7 +474,7 @@ static inline u16 _inw(unsigned long addr)
        u16 val;
 
        __io_pbr();
-       val = __le16_to_cpu(__raw_readw(PCI_IOBASE + addr));
+       val = __le16_to_cpu((__le16 __force)__raw_readw(PCI_IOBASE + addr));
        __io_par(val);
        return val;
 }
@@ -487,7 +487,7 @@ static inline u32 _inl(unsigned long addr)
        u32 val;
 
        __io_pbr();
-       val = __le32_to_cpu(__raw_readl(PCI_IOBASE + addr));
+       val = __le32_to_cpu((__le32 __force)__raw_readl(PCI_IOBASE + addr));
        __io_par(val);
        return val;
 }
@@ -508,7 +508,7 @@ static inline void _outb(u8 value, unsigned long addr)
 static inline void _outw(u16 value, unsigned long addr)
 {
        __io_pbw();
-       __raw_writew(cpu_to_le16(value), PCI_IOBASE + addr);
+       __raw_writew((u16 __force)cpu_to_le16(value), PCI_IOBASE + addr);
        __io_paw();
 }
 #endif
@@ -518,7 +518,7 @@ static inline void _outw(u16 value, unsigned long addr)
 static inline void _outl(u32 value, unsigned long addr)
 {
        __io_pbw();
-       __raw_writel(cpu_to_le32(value), PCI_IOBASE + addr);
+       __raw_writel((u32 __force)cpu_to_le32(value), PCI_IOBASE + addr);
        __io_paw();
 }
 #endif
index 9d28a5e..6492246 100644 (file)
  * in the low address range. Architectures for which this is not
  * true can't use this generic implementation.
  */
-extern unsigned int ioread8(void __iomem *);
-extern unsigned int ioread16(void __iomem *);
-extern unsigned int ioread16be(void __iomem *);
-extern unsigned int ioread32(void __iomem *);
-extern unsigned int ioread32be(void __iomem *);
+extern unsigned int ioread8(const void __iomem *);
+extern unsigned int ioread16(const void __iomem *);
+extern unsigned int ioread16be(const void __iomem *);
+extern unsigned int ioread32(const void __iomem *);
+extern unsigned int ioread32be(const void __iomem *);
 #ifdef CONFIG_64BIT
-extern u64 ioread64(void __iomem *);
-extern u64 ioread64be(void __iomem *);
+extern u64 ioread64(const void __iomem *);
+extern u64 ioread64be(const void __iomem *);
 #endif
 
 #ifdef readq
@@ -41,10 +41,10 @@ extern u64 ioread64be(void __iomem *);
 #define ioread64_hi_lo ioread64_hi_lo
 #define ioread64be_lo_hi ioread64be_lo_hi
 #define ioread64be_hi_lo ioread64be_hi_lo
-extern u64 ioread64_lo_hi(void __iomem *addr);
-extern u64 ioread64_hi_lo(void __iomem *addr);
-extern u64 ioread64be_lo_hi(void __iomem *addr);
-extern u64 ioread64be_hi_lo(void __iomem *addr);
+extern u64 ioread64_lo_hi(const void __iomem *addr);
+extern u64 ioread64_hi_lo(const void __iomem *addr);
+extern u64 ioread64be_lo_hi(const void __iomem *addr);
+extern u64 ioread64be_hi_lo(const void __iomem *addr);
 #endif
 
 extern void iowrite8(u8, void __iomem *);
@@ -79,9 +79,9 @@ extern void iowrite64be_hi_lo(u64 val, void __iomem *addr);
  * memory across multiple ports, use "memcpy_toio()"
  * and friends.
  */
-extern void ioread8_rep(void __iomem *port, void *buf, unsigned long count);
-extern void ioread16_rep(void __iomem *port, void *buf, unsigned long count);
-extern void ioread32_rep(void __iomem *port, void *buf, unsigned long count);
+extern void ioread8_rep(const void __iomem *port, void *buf, unsigned long count);
+extern void ioread16_rep(const void __iomem *port, void *buf, unsigned long count);
+extern void ioread32_rep(const void __iomem *port, void *buf, unsigned long count);
 
 extern void iowrite8_rep(void __iomem *port, const void *buf, unsigned long count);
 extern void iowrite16_rep(void __iomem *port, const void *buf, unsigned long count);
index 1c4fd95..c5edc5e 100644 (file)
@@ -168,7 +168,6 @@ void hyperv_report_panic_msg(phys_addr_t pa, size_t size);
 bool hv_is_hyperv_initialized(void);
 bool hv_is_hibernation_supported(void);
 void hyperv_cleanup(void);
-void hv_setup_sched_clock(void *sched_clock);
 #else /* CONFIG_HYPERV */
 static inline bool hv_is_hyperv_initialized(void) { return false; }
 static inline bool hv_is_hibernation_supported(void) { return false; }
index 6f44810..02932ef 100644 (file)
@@ -147,7 +147,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
 
 #if CONFIG_PGTABLE_LEVELS > 3
 
-#ifndef __HAVE_ARCH_PUD_FREE
+#ifndef __HAVE_ARCH_PUD_ALLOC_ONE
 /**
  * pud_alloc_one - allocate a page for PUD-level page table
  * @mm: the mm_struct of the current context
index 7616ff0..5430feb 100644 (file)
  */
 #ifndef RO_AFTER_INIT_DATA
 #define RO_AFTER_INIT_DATA                                             \
+       . = ALIGN(8);                                                   \
        __start_ro_after_init = .;                                      \
        *(.data..ro_after_init)                                         \
        JUMP_TABLE_DATA                                                 \
index c4255d8..d38c4d7 100644 (file)
@@ -851,7 +851,6 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
 asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32);
 asmlinkage long compat_sys_recv(int fd, void __user *buf, compat_size_t len,
                                unsigned flags);
-asmlinkage long compat_sys_sysctl(struct compat_sysctl_args __user *args);
 
 /* obsolete: fs/readdir.c */
 asmlinkage long compat_sys_old_readdir(unsigned int fd,
index 58687a5..8f141d4 100644 (file)
@@ -576,6 +576,8 @@ unsigned int cpufreq_driver_resolve_freq(struct cpufreq_policy *policy,
 unsigned int cpufreq_policy_transition_delay_us(struct cpufreq_policy *policy);
 int cpufreq_register_governor(struct cpufreq_governor *governor);
 void cpufreq_unregister_governor(struct cpufreq_governor *governor);
+int cpufreq_start_governor(struct cpufreq_policy *policy);
+void cpufreq_stop_governor(struct cpufreq_policy *policy);
 
 #define cpufreq_governor_init(__governor)                      \
 static int __init __governor##_init(void)                      \
index 4208f94..7b3b04b 100644 (file)
@@ -67,8 +67,6 @@ extern void debug_dma_sync_sg_for_device(struct device *dev,
 
 extern void debug_dma_dump_mappings(struct device *dev);
 
-extern void debug_dma_assert_idle(struct page *page);
-
 #else /* CONFIG_DMA_API_DEBUG */
 
 static inline void dma_debug_add_bus(struct bus_type *bus)
@@ -157,10 +155,6 @@ static inline void debug_dma_dump_mappings(struct device *dev)
 {
 }
 
-static inline void debug_dma_assert_idle(struct page *page)
-{
-}
-
 #endif /* CONFIG_DMA_API_DEBUG */
 
 #endif /* __DMA_DEBUG_H */
index 7c69dd7..e019ea2 100644 (file)
@@ -3322,7 +3322,7 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, rwf_t flags)
        if (flags & RWF_NOWAIT) {
                if (!(ki->ki_filp->f_mode & FMODE_NOWAIT))
                        return -EOPNOTSUPP;
-               kiocb_flags |= IOCB_NOWAIT;
+               kiocb_flags |= IOCB_NOWAIT | IOCB_NOIO;
        }
        if (flags & RWF_HIPRI)
                kiocb_flags |= IOCB_HIPRI;
index 4673020..8a8bc46 100644 (file)
@@ -258,9 +258,36 @@ static inline spinlock_t *pud_trans_huge_lock(pud_t *pud,
        else
                return NULL;
 }
-static inline int hpage_nr_pages(struct page *page)
+
+/**
+ * thp_head - Head page of a transparent huge page.
+ * @page: Any page (tail, head or regular) found in the page cache.
+ */
+static inline struct page *thp_head(struct page *page)
+{
+       return compound_head(page);
+}
+
+/**
+ * thp_order - Order of a transparent huge page.
+ * @page: Head page of a transparent huge page.
+ */
+static inline unsigned int thp_order(struct page *page)
+{
+       VM_BUG_ON_PGFLAGS(PageTail(page), page);
+       if (PageHead(page))
+               return HPAGE_PMD_ORDER;
+       return 0;
+}
+
+/**
+ * thp_nr_pages - The number of regular pages in this huge page.
+ * @page: The head page of a huge page.
+ */
+static inline int thp_nr_pages(struct page *page)
 {
-       if (unlikely(PageTransHuge(page)))
+       VM_BUG_ON_PGFLAGS(PageTail(page), page);
+       if (PageHead(page))
                return HPAGE_PMD_NR;
        return 1;
 }
@@ -317,9 +344,21 @@ static inline struct list_head *page_deferred_list(struct page *page)
 #define HPAGE_PUD_MASK ({ BUILD_BUG(); 0; })
 #define HPAGE_PUD_SIZE ({ BUILD_BUG(); 0; })
 
-static inline int hpage_nr_pages(struct page *page)
+static inline struct page *thp_head(struct page *page)
 {
-       VM_BUG_ON_PAGE(PageTail(page), page);
+       VM_BUG_ON_PGFLAGS(PageTail(page), page);
+       return page;
+}
+
+static inline unsigned int thp_order(struct page *page)
+{
+       VM_BUG_ON_PGFLAGS(PageTail(page), page);
+       return 0;
+}
+
+static inline int thp_nr_pages(struct page *page)
+{
+       VM_BUG_ON_PGFLAGS(PageTail(page), page);
        return 1;
 }
 
@@ -443,4 +482,15 @@ static inline bool thp_migration_supported(void)
 }
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
+/**
+ * thp_size - Size of a transparent huge page.
+ * @page: Head page of a transparent huge page.
+ *
+ * Return: Number of bytes in this page.
+ */
+static inline unsigned long thp_size(struct page *page)
+{
+       return PAGE_SIZE << thp_order(page);
+}
+
 #endif /* _LINUX_HUGE_MM_H */
index d7d4250..78dd703 100644 (file)
@@ -72,7 +72,6 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr,
                            void *context);
 
 extern int register_perf_hw_breakpoint(struct perf_event *bp);
-extern int __register_perf_hw_breakpoint(struct perf_event *bp);
 extern void unregister_hw_breakpoint(struct perf_event *bp);
 extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events);
 
@@ -119,8 +118,6 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr,
                            void *context)              { return NULL; }
 static inline int
 register_perf_hw_breakpoint(struct perf_event *bp)     { return -ENOSYS; }
-static inline int
-__register_perf_hw_breakpoint(struct perf_event *bp)   { return -ENOSYS; }
 static inline void unregister_hw_breakpoint(struct perf_event *bp)     { }
 static inline void
 unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events)        { }
index ae21b72..f32522b 100644 (file)
@@ -57,7 +57,7 @@ static inline void hi_lo_writeq_relaxed(__u64 val, volatile void __iomem *addr)
 
 #ifndef ioread64_hi_lo
 #define ioread64_hi_lo ioread64_hi_lo
-static inline u64 ioread64_hi_lo(void __iomem *addr)
+static inline u64 ioread64_hi_lo(const void __iomem *addr)
 {
        u32 low, high;
 
@@ -79,7 +79,7 @@ static inline void iowrite64_hi_lo(u64 val, void __iomem *addr)
 
 #ifndef ioread64be_hi_lo
 #define ioread64be_hi_lo ioread64be_hi_lo
-static inline u64 ioread64be_hi_lo(void __iomem *addr)
+static inline u64 ioread64be_hi_lo(const void __iomem *addr)
 {
        u32 low, high;
 
index faaa842..448a214 100644 (file)
@@ -57,7 +57,7 @@ static inline void lo_hi_writeq_relaxed(__u64 val, volatile void __iomem *addr)
 
 #ifndef ioread64_lo_hi
 #define ioread64_lo_hi ioread64_lo_hi
-static inline u64 ioread64_lo_hi(void __iomem *addr)
+static inline u64 ioread64_lo_hi(const void __iomem *addr)
 {
        u32 low, high;
 
@@ -79,7 +79,7 @@ static inline void iowrite64_lo_hi(u64 val, void __iomem *addr)
 
 #ifndef ioread64be_lo_hi
 #define ioread64be_lo_hi ioread64be_lo_hi
-static inline u64 ioread64be_lo_hi(void __iomem *addr)
+static inline u64 ioread64be_lo_hi(const void __iomem *addr)
 {
        u32 low, high;
 
index 385237e..d0b0361 100644 (file)
@@ -630,7 +630,7 @@ unsigned long mem_cgroup_get_zone_lru_size(struct lruvec *lruvec,
        struct mem_cgroup_per_node *mz;
 
        mz = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
-       return mz->lru_zone_size[zone_idx][lru];
+       return READ_ONCE(mz->lru_zone_size[zone_idx][lru]);
 }
 
 void mem_cgroup_handle_over_high(void);
index ab76cdd..4b35baa 100644 (file)
@@ -14,7 +14,7 @@
 
 #define MFD_RES_SIZE(arr) (sizeof(arr) / sizeof(struct resource))
 
-#define MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, _match)\
+#define MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, _of_reg, _use_of_reg, _match) \
        {                                                               \
                .name = (_name),                                        \
                .resources = (_res),                                    \
                .platform_data = (_pdata),                              \
                .pdata_size = (_pdsize),                                \
                .of_compatible = (_compat),                             \
+               .of_reg = (_of_reg),                                    \
+               .use_of_reg = (_use_of_reg),                            \
                .acpi_match = (_match),                                 \
                .id = (_id),                                            \
        }
 
-#define OF_MFD_CELL(_name, _res, _pdata, _pdsize,_id, _compat)         \
-       MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, NULL)  \
+#define OF_MFD_CELL_REG(_name, _res, _pdata, _pdsize, _id, _compat, _of_reg) \
+       MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, _of_reg, true, NULL)
 
-#define ACPI_MFD_CELL(_name, _res, _pdata, _pdsize, _id, _match)       \
-       MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, _match)   \
+#define OF_MFD_CELL(_name, _res, _pdata, _pdsize, _id, _compat) \
+       MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, _compat, 0, false, NULL)
 
-#define MFD_CELL_BASIC(_name, _res, _pdata, _pdsize, _id)              \
-       MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, NULL)     \
+#define ACPI_MFD_CELL(_name, _res, _pdata, _pdsize, _id, _match) \
+       MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, 0, false, _match)
 
-#define MFD_CELL_RES(_name, _res)                                      \
-       MFD_CELL_ALL(_name, _res, NULL, 0, 0, NULL, NULL)               \
+#define MFD_CELL_BASIC(_name, _res, _pdata, _pdsize, _id) \
+       MFD_CELL_ALL(_name, _res, _pdata, _pdsize, _id, NULL, 0, false, NULL)
 
-#define MFD_CELL_NAME(_name)                                           \
-       MFD_CELL_ALL(_name, NULL, NULL, 0, 0, NULL, NULL)               \
+#define MFD_CELL_RES(_name, _res) \
+       MFD_CELL_ALL(_name, _res, NULL, 0, 0, NULL, 0, false, NULL)
+
+#define MFD_CELL_NAME(_name) \
+       MFD_CELL_ALL(_name, NULL, NULL, 0, 0, NULL, 0, false, NULL)
+
+#define MFD_DEP_LEVEL_NORMAL 0
+#define MFD_DEP_LEVEL_HIGH 1
 
 struct irq_domain;
 struct property_entry;
@@ -58,6 +66,7 @@ struct mfd_cell_acpi_match {
 struct mfd_cell {
        const char              *name;
        int                     id;
+       int                     level;
 
        int                     (*enable)(struct platform_device *dev);
        int                     (*disable)(struct platform_device *dev);
@@ -78,6 +87,16 @@ struct mfd_cell {
         */
        const char              *of_compatible;
 
+       /*
+        * Address as defined in Device Tree.  Used to compement 'of_compatible'
+        * (above) when matching OF nodes with devices that have identical
+        * compatible strings
+        */
+       const u64 of_reg;
+
+       /* Set to 'true' to use 'of_reg' (above) - allows for of_reg=0 */
+       bool use_of_reg;
+
        /* Matches ACPI */
        const struct mfd_cell_acpi_match        *acpi_match;
 
@@ -135,6 +154,7 @@ static inline int mfd_add_hotplug_devices(struct device *parent,
 }
 
 extern void mfd_remove_devices(struct device *parent);
+extern void mfd_remove_devices_late(struct device *parent);
 
 extern int devm_mfd_add_devices(struct device *dev, int id,
                                const struct mfd_cell *cells, int n_devs,
index eac48e4..d3f1269 100644 (file)
@@ -35,7 +35,7 @@ struct da9055_pdata {
        int *gpio_rsel;
        /*
         * Regulator mode control bits value (GPI offset) that
-        * that controls the regulator state, 0 if not available.
+        * controls the regulator state, 0 if not available.
         */
        enum gpio_select *reg_ren;
        /*
index 5cd06ab..fa7a43f 100644 (file)
@@ -35,6 +35,7 @@ enum da9063_variant_codes {
        PMIC_DA9063_AD = 0x3,
        PMIC_DA9063_BB = 0x5,
        PMIC_DA9063_CA = 0x6,
+       PMIC_DA9063_DA = 0x7,
 };
 
 /* Interrupts */
index ba706b0..1dbabf1 100644 (file)
 #define        DA9063_BB_REG_GP_ID_19          0x134
 
 /* Chip ID and variant */
-#define        DA9063_REG_CHIP_ID              0x181
-#define        DA9063_REG_CHIP_VARIANT         0x182
+#define        DA9063_REG_DEVICE_ID            0x181
+#define        DA9063_REG_VARIANT_ID           0x182
+#define        DA9063_REG_CUSTOMER_ID          0x183
+#define        DA9063_REG_CONFIG_ID            0x184
 
 /*
  * PMIC registers bits
 #define        DA9063_RTC_CLOCK                        0x40
 #define        DA9063_OUT_32K_EN                       0x80
 
-/* DA9063_REG_CHIP_VARIANT */
-#define        DA9063_CHIP_VARIANT_SHIFT               4
-
 /* DA9063_REG_BUCK_ILIM_A (addr=0x9A) */
 #define DA9063_BIO_ILIM_MASK                   0x0F
 #define DA9063_BMEM_ILIM_MASK                  0xF0
 #define                DA9063_MON_A10_IDX_LDO9         0x04
 #define                DA9063_MON_A10_IDX_LDO10        0x05
 
+/* DA9063_REG_VARIANT_ID (addr=0x182) */
+#define        DA9063_VARIANT_ID_VRC_SHIFT             0
+#define DA9063_VARIANT_ID_VRC_MASK             0x0F
+#define        DA9063_VARIANT_ID_MRC_SHIFT             4
+#define DA9063_VARIANT_ID_MRC_MASK             0xF0
+
 #endif /* _DA9063_REG_H */
index bbc6448..2cadf88 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
  *              http://www.hisilicon.com
  * Copyright (c) <2013-2014> Linaro Ltd.
- *              http://www.linaro.org
+ *              https://www.linaro.org
  *
  * Author: Guodong Xu <guodong.xu@linaro.org>
  */
diff --git a/include/linux/mfd/khadas-mcu.h b/include/linux/mfd/khadas-mcu.h
new file mode 100644 (file)
index 0000000..a99ba2e
--- /dev/null
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Khadas System control Microcontroller Register map
+ *
+ * Copyright (C) 2020 BayLibre SAS
+ *
+ * Author(s): Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef MFD_KHADAS_MCU_H
+#define MFD_KHADAS_MCU_H
+
+#define KHADAS_MCU_PASSWD_VEN_0_REG            0x00 /* RO */
+#define KHADAS_MCU_PASSWD_VEN_1_REG            0x01 /* RO */
+#define KHADAS_MCU_PASSWD_VEN_2_REG            0x02 /* RO */
+#define KHADAS_MCU_PASSWD_VEN_3_REG            0x03 /* RO */
+#define KHADAS_MCU_PASSWD_VEN_4_REG            0x04 /* RO */
+#define KHADAS_MCU_PASSWD_VEN_5_REG            0x05 /* RO */
+#define KHADAS_MCU_MAC_0_REG                   0x06 /* RO */
+#define KHADAS_MCU_MAC_1_REG                   0x07 /* RO */
+#define KHADAS_MCU_MAC_2_REG                   0x08 /* RO */
+#define KHADAS_MCU_MAC_3_REG                   0x09 /* RO */
+#define KHADAS_MCU_MAC_4_REG                   0x0a /* RO */
+#define KHADAS_MCU_MAC_5_REG                   0x0b /* RO */
+#define KHADAS_MCU_USID_0_REG                  0x0c /* RO */
+#define KHADAS_MCU_USID_1_REG                  0x0d /* RO */
+#define KHADAS_MCU_USID_2_REG                  0x0e /* RO */
+#define KHADAS_MCU_USID_3_REG                  0x0f /* RO */
+#define KHADAS_MCU_USID_4_REG                  0x10 /* RO */
+#define KHADAS_MCU_USID_5_REG                  0x11 /* RO */
+#define KHADAS_MCU_VERSION_0_REG               0x12 /* RO */
+#define KHADAS_MCU_VERSION_1_REG               0x13 /* RO */
+#define KHADAS_MCU_DEVICE_NO_0_REG             0x14 /* RO */
+#define KHADAS_MCU_DEVICE_NO_1_REG             0x15 /* RO */
+#define KHADAS_MCU_FACTORY_TEST_REG            0x16 /* R */
+#define KHADAS_MCU_BOOT_MODE_REG               0x20 /* RW */
+#define KHADAS_MCU_BOOT_EN_WOL_REG             0x21 /* RW */
+#define KHADAS_MCU_BOOT_EN_RTC_REG             0x22 /* RW */
+#define KHADAS_MCU_BOOT_EN_EXP_REG             0x23 /* RW */
+#define KHADAS_MCU_BOOT_EN_IR_REG              0x24 /* RW */
+#define KHADAS_MCU_BOOT_EN_DCIN_REG            0x25 /* RW */
+#define KHADAS_MCU_BOOT_EN_KEY_REG             0x26 /* RW */
+#define KHADAS_MCU_KEY_MODE_REG                        0x27 /* RW */
+#define KHADAS_MCU_LED_MODE_ON_REG             0x28 /* RW */
+#define KHADAS_MCU_LED_MODE_OFF_REG            0x29 /* RW */
+#define KHADAS_MCU_SHUTDOWN_NORMAL_REG         0x2c /* RW */
+#define KHADAS_MCU_MAC_SWITCH_REG              0x2d /* RW */
+#define KHADAS_MCU_MCU_SLEEP_MODE_REG          0x2e /* RW */
+#define KHADAS_MCU_IR_CODE1_0_REG              0x2f /* RW */
+#define KHADAS_MCU_IR_CODE1_1_REG              0x30 /* RW */
+#define KHADAS_MCU_IR_CODE1_2_REG              0x31 /* RW */
+#define KHADAS_MCU_IR_CODE1_3_REG              0x32 /* RW */
+#define KHADAS_MCU_USB_PCIE_SWITCH_REG         0x33 /* RW */
+#define KHADAS_MCU_IR_CODE2_0_REG              0x34 /* RW */
+#define KHADAS_MCU_IR_CODE2_1_REG              0x35 /* RW */
+#define KHADAS_MCU_IR_CODE2_2_REG              0x36 /* RW */
+#define KHADAS_MCU_IR_CODE2_3_REG              0x37 /* RW */
+#define KHADAS_MCU_PASSWD_USER_0_REG           0x40 /* RW */
+#define KHADAS_MCU_PASSWD_USER_1_REG           0x41 /* RW */
+#define KHADAS_MCU_PASSWD_USER_2_REG           0x42 /* RW */
+#define KHADAS_MCU_PASSWD_USER_3_REG           0x43 /* RW */
+#define KHADAS_MCU_PASSWD_USER_4_REG           0x44 /* RW */
+#define KHADAS_MCU_PASSWD_USER_5_REG           0x45 /* RW */
+#define KHADAS_MCU_USER_DATA_0_REG             0x46 /* RW 56 bytes */
+#define KHADAS_MCU_PWR_OFF_CMD_REG             0x80 /* WO */
+#define KHADAS_MCU_PASSWD_START_REG            0x81 /* WO */
+#define KHADAS_MCU_CHECK_VEN_PASSWD_REG                0x82 /* WO */
+#define KHADAS_MCU_CHECK_USER_PASSWD_REG       0x83 /* WO */
+#define KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG  0x86 /* RO */
+#define KHADAS_MCU_WOL_INIT_START_REG          0x87 /* WO */
+#define KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG     0x88 /* WO */
+
+enum {
+       KHADAS_BOARD_VIM1 = 0x1,
+       KHADAS_BOARD_VIM2,
+       KHADAS_BOARD_VIM3,
+       KHADAS_BOARD_EDGE = 0x11,
+       KHADAS_BOARD_EDGE_V,
+};
+
+/**
+ * struct khadas_mcu - Khadas MCU structure
+ * @device:            device reference used for logs
+ * @regmap:            register map
+ */
+struct khadas_mcu {
+       struct device *dev;
+       struct regmap *regmap;
+};
+
+#endif /* MFD_KHADAS_MCU_H */
index edbec83..5546688 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Functions to access LP873X power management chip.
  *
- * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
index ce96535..43716ac 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Functions to access LP87565 power management chip.
  *
- * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2017 Texas Instruments Incorporated - https://www.ti.com/
  */
 
 #ifndef __LINUX_MFD_LP87565_H
index fa9595d..601cbbc 100644 (file)
@@ -21,7 +21,6 @@
 
 struct gpio_desc;
 struct pinctrl_map;
-struct madera_codec_pdata;
 
 /**
  * struct madera_pdata - Configuration data for Madera devices
index e798c81..311f7d3 100644 (file)
@@ -131,7 +131,7 @@ enum max77693_pmic_reg {
 #define FLASH_INT_FLED1_SHORT  BIT(3)
 #define FLASH_INT_OVER_CURRENT BIT(4)
 
-/* Fast charge timer in in hours */
+/* Fast charge timer in hours */
 #define DEFAULT_FAST_CHARGE_TIMER              4
 /* microamps */
 #define DEFAULT_TOP_OFF_THRESHOLD_CURRENT      150000
diff --git a/include/linux/mfd/smsc.h b/include/linux/mfd/smsc.h
deleted file mode 100644 (file)
index 8394412..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * SMSC ECE1099
- *
- * Copyright 2012 Texas Instruments Inc.
- *
- * Author: Sourav Poddar <sourav.poddar@ti.com>
- */
-
-#ifndef __LINUX_MFD_SMSC_H
-#define __LINUX_MFD_SMSC_H
-
-#include <linux/regmap.h>
-
-#define SMSC_ID_ECE1099                        1
-#define SMSC_NUM_CLIENTS               2
-
-#define SMSC_BASE_ADDR                 0x38
-#define OMAP_GPIO_SMSC_IRQ             151
-
-#define SMSC_MAXGPIO         32
-#define SMSC_BANK(offs)      ((offs) >> 3)
-#define SMSC_BIT(offs)       (1u << ((offs) & 0x7))
-
-struct smsc {
-       struct device *dev;
-       struct i2c_client *i2c_clients[SMSC_NUM_CLIENTS];
-       struct regmap *regmap;
-       int clk;
-       /* Stored chip id */
-       int id;
-};
-
-struct smsc_gpio;
-struct smsc_keypad;
-
-static inline int smsc_read(struct device *child, unsigned int reg,
-       unsigned int *dest)
-{
-       struct smsc     *smsc = dev_get_drvdata(child->parent);
-
-       return regmap_read(smsc->regmap, reg, dest);
-}
-
-static inline int smsc_write(struct device *child, unsigned int reg,
-       unsigned int value)
-{
-       struct smsc     *smsc = dev_get_drvdata(child->parent);
-
-       return regmap_write(smsc->regmap, reg, value);
-}
-
-/* Registers for SMSC */
-#define SMSC_RESET                                             0xF5
-#define SMSC_GRP_INT                                           0xF9
-#define SMSC_CLK_CTRL                                          0xFA
-#define SMSC_WKUP_CTRL                                         0xFB
-#define SMSC_DEV_ID                                            0xFC
-#define SMSC_DEV_REV                                           0xFD
-#define SMSC_VEN_ID_L                                          0xFE
-#define SMSC_VEN_ID_H                                          0xFF
-
-/* CLK VALUE */
-#define SMSC_CLK_VALUE                                         0x13
-
-/* Registers for function GPIO INPUT */
-#define SMSC_GPIO_DATA_IN_START                                        0x00
-
-/* Registers for function GPIO OUPUT */
-#define SMSC_GPIO_DATA_OUT_START                                       0x05
-
-/* Definitions for SMSC GPIO CONFIGURATION REGISTER*/
-#define SMSC_GPIO_INPUT_LOW                                    0x01
-#define SMSC_GPIO_INPUT_RISING                                 0x09
-#define SMSC_GPIO_INPUT_FALLING                                        0x11
-#define SMSC_GPIO_INPUT_BOTH_EDGE                              0x19
-#define SMSC_GPIO_OUTPUT_PP                                    0x21
-#define SMSC_GPIO_OUTPUT_OP                                    0x31
-
-#define GRP_INT_STAT                                           0xf9
-#define        SMSC_GPI_INT                                            0x0f
-#define SMSC_CFG_START                                         0x0A
-
-/* Registers for SMSC GPIO INTERRUPT STATUS REGISTER*/
-#define SMSC_GPIO_INT_STAT_START                                  0x32
-
-/* Registers for SMSC GPIO INTERRUPT MASK REGISTER*/
-#define SMSC_GPIO_INT_MASK_START                               0x37
-
-/* Registers for SMSC function KEYPAD*/
-#define SMSC_KP_OUT                                            0x40
-#define SMSC_KP_IN                                             0x41
-#define SMSC_KP_INT_STAT                                       0x42
-#define SMSC_KP_INT_MASK                                       0x43
-
-/* Definitions for keypad */
-#define SMSC_KP_KSO           0x70
-#define SMSC_KP_KSI           0x51
-#define SMSC_KSO_ALL_LOW        0x20
-#define SMSC_KP_SET_LOW_PWR        0x0B
-#define SMSC_KP_SET_HIGH           0xFF
-#define SMSC_KSO_EVAL           0x00
-
-#endif /*  __LINUX_MFD_SMSC_H */
index 605f622..90b2055 100644 (file)
 #define STM32_LPTIM_CMPOK              BIT(3)
 
 /* STM32_LPTIM_ICR - bit fields */
+#define STM32_LPTIM_ARRMCF             BIT(1)
 #define STM32_LPTIM_CMPOKCF_ARROKCF    GENMASK(4, 3)
 
+/* STM32_LPTIM_IER - bit flieds */
+#define STM32_LPTIM_ARRMIE     BIT(1)
+
 /* STM32_LPTIM_CR - bit fields */
 #define STM32_LPTIM_CNTSTRT    BIT(2)
+#define STM32_LPTIM_SNGSTRT    BIT(1)
 #define STM32_LPTIM_ENABLE     BIT(0)
 
 /* STM32_LPTIM_CFGR - bit fields */
index 4831684..ffc091b 100644 (file)
@@ -4,7 +4,7 @@
 /*
  * TI Touch Screen / ADC MFD driver
  *
- * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2012 Texas Instruments Incorporated - https://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
index a228ae4..e0a417e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
  *     Andrew F. Davis <afd@ti.com>
  *
  * This program is free software; you can redistribute it and/or
index b5dd108..db70918 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Functions to access TPS65217 power management chip.
  *
- * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
index b0470c3..f4ca367 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Functions to access TPS65219 power management chip.
  *
- * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2014 Texas Instruments Incorporated - https://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License version 2 as
index b25d029..7943e41 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
  *     Andrew F. Davis <afd@ti.com>
  *
  * This program is free software; you can redistribute it and/or
index e7602a3..1983e08 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/resource.h>
 #include <linux/page_ext.h>
 #include <linux/err.h>
+#include <linux/page-flags.h>
 #include <linux/page_ref.h>
 #include <linux/memremap.h>
 #include <linux/overflow.h>
@@ -668,11 +669,6 @@ int vma_is_stack_for_current(struct vm_area_struct *vma);
 struct mmu_gather;
 struct inode;
 
-/*
- * FIXME: take this include out, include page-flags.h in
- * files which need it (119 of them)
- */
-#include <linux/page-flags.h>
 #include <linux/huge_mm.h>
 
 /*
@@ -922,12 +918,15 @@ static inline int compound_pincount(struct page *page)
 static inline void set_compound_order(struct page *page, unsigned int order)
 {
        page[1].compound_order = order;
+       page[1].compound_nr = 1U << order;
 }
 
 /* Returns the number of pages in this potentially compound page. */
 static inline unsigned long compound_nr(struct page *page)
 {
-       return 1UL << compound_order(page);
+       if (!PageHead(page))
+               return 1;
+       return page[1].compound_nr;
 }
 
 /* Returns the number of bytes in this potentially compound page. */
@@ -1068,6 +1067,7 @@ vm_fault_t finish_mkwrite_fault(struct vm_fault *vmf);
 
 static inline enum zone_type page_zonenum(const struct page *page)
 {
+       ASSERT_EXCLUSIVE_BITS(page->flags, ZONES_MASK << ZONES_PGSHIFT);
        return (page->flags >> ZONES_PGSHIFT) & ZONES_MASK;
 }
 
@@ -1595,6 +1595,7 @@ static inline void clear_page_pfmemalloc(struct page *page)
 extern void pagefault_out_of_memory(void);
 
 #define offset_in_page(p)      ((unsigned long)(p) & ~PAGE_MASK)
+#define offset_in_thp(page, p) ((unsigned long)(p) & (thp_size(page) - 1))
 
 /*
  * Flags passed to show_mem() and show_free_areas() to suppress output in
index 219bef4..8fc71e9 100644 (file)
@@ -48,14 +48,14 @@ static __always_inline void update_lru_size(struct lruvec *lruvec,
 static __always_inline void add_page_to_lru_list(struct page *page,
                                struct lruvec *lruvec, enum lru_list lru)
 {
-       update_lru_size(lruvec, lru, page_zonenum(page), hpage_nr_pages(page));
+       update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page));
        list_add(&page->lru, &lruvec->lists[lru]);
 }
 
 static __always_inline void add_page_to_lru_list_tail(struct page *page,
                                struct lruvec *lruvec, enum lru_list lru)
 {
-       update_lru_size(lruvec, lru, page_zonenum(page), hpage_nr_pages(page));
+       update_lru_size(lruvec, lru, page_zonenum(page), thp_nr_pages(page));
        list_add_tail(&page->lru, &lruvec->lists[lru]);
 }
 
@@ -63,7 +63,7 @@ static __always_inline void del_page_from_lru_list(struct page *page,
                                struct lruvec *lruvec, enum lru_list lru)
 {
        list_del(&page->lru);
-       update_lru_size(lruvec, lru, page_zonenum(page), -hpage_nr_pages(page));
+       update_lru_size(lruvec, lru, page_zonenum(page), -thp_nr_pages(page));
 }
 
 /**
index 0277fba..496c3ff 100644 (file)
@@ -134,6 +134,7 @@ struct page {
                        unsigned char compound_dtor;
                        unsigned char compound_order;
                        atomic_t compound_mapcount;
+                       unsigned int compound_nr; /* 1 << compound_order */
                };
                struct {        /* Second tail page of compound page */
                        unsigned long _compound_pad_1;  /* compound_head */
index 2e66708..e30ed5f 100644 (file)
@@ -389,6 +389,7 @@ struct module {
        unsigned int num_gpl_syms;
        const struct kernel_symbol *gpl_syms;
        const s32 *gpl_crcs;
+       bool using_gplonly_symbols;
 
 #ifdef CONFIG_UNUSED_SYMBOLS
        /* unused exported symbols. */
@@ -582,34 +583,14 @@ struct module *find_module(const char *name);
 struct symsearch {
        const struct kernel_symbol *start, *stop;
        const s32 *crcs;
-       enum {
+       enum mod_license {
                NOT_GPL_ONLY,
                GPL_ONLY,
                WILL_BE_GPL_ONLY,
-       } licence;
+       } license;
        bool unused;
 };
 
-/*
- * Search for an exported symbol by name.
- *
- * Must be called with module_mutex held or preemption disabled.
- */
-const struct kernel_symbol *find_symbol(const char *name,
-                                       struct module **owner,
-                                       const s32 **crc,
-                                       bool gplok,
-                                       bool warn);
-
-/*
- * Walk the exported symbol table
- *
- * Must be called with module_mutex held or preemption disabled.
- */
-bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
-                                   struct module *owner,
-                                   void *data), void *data);
-
 /* Returns 0 and fills in value, defined and namebuf, or -ERANGE if
    symnum out of range. */
 int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
@@ -657,7 +638,6 @@ static inline void __module_get(struct module *module)
 #define symbol_put_addr(p) do { } while (0)
 
 #endif /* CONFIG_MODULE_UNLOAD */
-int ref_module(struct module *a, struct module *b);
 
 /* This is a #define so the string doesn't get put in every .o file */
 #define module_name(mod)                       \
index 3ef917f..1ad5aa3 100644 (file)
@@ -108,7 +108,7 @@ struct kparam_array
  * ".") the kernel commandline parameter.  Note that - is changed to _, so
  * the user can use "foo-bar=1" even for variable "foo_bar".
  *
- * @perm is 0 if the the variable is not to appear in sysfs, or 0444
+ * @perm is 0 if the variable is not to appear in sysfs, or 0444
  * for world-readable, 0644 for root-writable, etc.  Note that if it
  * is writable, you may need to use kernel_param_lock() around
  * accesses (esp. charp, which can be kfreed when it changes).
index aac42c2..9b67394 100644 (file)
@@ -58,7 +58,6 @@ struct nf_ipv6_ops {
                        int (*output)(struct net *, struct sock *, struct sk_buff *));
        int (*reroute)(struct sk_buff *skb, const struct nf_queue_entry *entry);
 #if IS_MODULE(CONFIG_IPV6)
-       int (*br_defrag)(struct net *net, struct sk_buff *skb, u32 user);
        int (*br_fragment)(struct net *net, struct sock *sk,
                           struct sk_buff *skb,
                           struct nf_bridge_frag_data *data,
@@ -117,23 +116,6 @@ static inline int nf_ip6_route(struct net *net, struct dst_entry **dst,
 
 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
 
-static inline int nf_ipv6_br_defrag(struct net *net, struct sk_buff *skb,
-                                   u32 user)
-{
-#if IS_MODULE(CONFIG_IPV6)
-       const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
-
-       if (!v6_ops)
-               return 1;
-
-       return v6_ops->br_defrag(net, skb, user);
-#elif IS_BUILTIN(CONFIG_IPV6)
-       return nf_ct_frag6_gather(net, skb, user);
-#else
-       return 1;
-#endif
-}
-
 int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
                    struct nf_bridge_frag_data *data,
                    int (*output)(struct net *, struct sock *sk,
index 33ebe47..b8360be 100644 (file)
@@ -553,6 +553,11 @@ enum {
        NFSPROC4_CLNT_LAYOUTERROR,
 
        NFSPROC4_CLNT_COPY_NOTIFY,
+
+       NFSPROC4_CLNT_GETXATTR,
+       NFSPROC4_CLNT_SETXATTR,
+       NFSPROC4_CLNT_LISTXATTRS,
+       NFSPROC4_CLNT_REMOVEXATTR,
 };
 
 /* nfs41 types */
index 6ee9119..a2c6455 100644 (file)
@@ -102,6 +102,8 @@ struct nfs_delegation;
 
 struct posix_acl;
 
+struct nfs4_xattr_cache;
+
 /*
  * nfs fs inode data in memory
  */
@@ -188,6 +190,10 @@ struct nfs_inode {
        struct fscache_cookie   *fscache;
 #endif
        struct inode            vfs_inode;
+
+#ifdef CONFIG_NFS_V4_2
+       struct nfs4_xattr_cache *xattr_cache;
+#endif
 };
 
 struct nfs4_copy_state {
@@ -212,6 +218,9 @@ struct nfs4_copy_state {
 #define NFS_ACCESS_EXTEND      0x0008
 #define NFS_ACCESS_DELETE      0x0010
 #define NFS_ACCESS_EXECUTE     0x0020
+#define NFS_ACCESS_XAREAD      0x0040
+#define NFS_ACCESS_XAWRITE     0x0080
+#define NFS_ACCESS_XALIST      0x0100
 
 /*
  * Cache validity bit flags
@@ -231,6 +240,7 @@ struct nfs4_copy_state {
 #define NFS_INO_DATA_INVAL_DEFER       \
                                BIT(13)         /* Deferred cache invalidation */
 #define NFS_INO_INVALID_BLOCKS BIT(14)         /* cached blocks are invalid */
+#define NFS_INO_INVALID_XATTR  BIT(15)         /* xattrs are invalid */
 
 #define NFS_INO_INVALID_ATTR   (NFS_INO_INVALID_CHANGE \
                | NFS_INO_INVALID_CTIME \
@@ -490,6 +500,8 @@ extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
                        struct nfs_fattr *fattr, struct nfs4_label *label);
 extern int nfs_may_open(struct inode *inode, const struct cred *cred, int openflags);
 extern void nfs_access_zap_cache(struct inode *inode);
+extern int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res,
+                                bool may_block);
 
 /*
  * linux/fs/nfs/symlink.c
index 465fa98..7eae72a 100644 (file)
@@ -163,6 +163,11 @@ struct nfs_server {
        unsigned int            dtsize;         /* readdir size */
        unsigned short          port;           /* "port=" setting */
        unsigned int            bsize;          /* server block size */
+#ifdef CONFIG_NFS_V4_2
+       unsigned int            gxasize;        /* getxattr size */
+       unsigned int            sxasize;        /* setxattr size */
+       unsigned int            lxasize;        /* listxattr size */
+#endif
        unsigned int            acregmin;       /* attr cache timeouts */
        unsigned int            acregmax;
        unsigned int            acdirmin;
@@ -281,5 +286,6 @@ struct nfs_server {
 #define NFS_CAP_OFFLOAD_CANCEL (1U << 25)
 #define NFS_CAP_LAYOUTERROR    (1U << 26)
 #define NFS_CAP_COPY_NOTIFY    (1U << 27)
+#define NFS_CAP_XATTR          (1U << 28)
 
 #endif
index 5fd0a9e..9408f32 100644 (file)
@@ -150,6 +150,7 @@ struct nfs_fsinfo {
        __u32                   layouttype[NFS_MAX_LAYOUT_TYPES]; /* supported pnfs layout driver */
        __u32                   blksize; /* preferred pnfs io block size */
        __u32                   clone_blksize; /* granularity of a CLONE operation */
+       __u32                   xattr_support; /* User xattrs supported */
 };
 
 struct nfs_fsstat {
@@ -1497,7 +1498,64 @@ struct nfs42_seek_res {
        u32     sr_eof;
        u64     sr_offset;
 };
-#endif
+
+struct nfs42_setxattrargs {
+       struct nfs4_sequence_args       seq_args;
+       struct nfs_fh                   *fh;
+       const char                      *xattr_name;
+       u32                             xattr_flags;
+       size_t                          xattr_len;
+       struct page                     **xattr_pages;
+};
+
+struct nfs42_setxattrres {
+       struct nfs4_sequence_res        seq_res;
+       struct nfs4_change_info         cinfo;
+};
+
+struct nfs42_getxattrargs {
+       struct nfs4_sequence_args       seq_args;
+       struct nfs_fh                   *fh;
+       const char                      *xattr_name;
+       size_t                          xattr_len;
+       struct page                     **xattr_pages;
+};
+
+struct nfs42_getxattrres {
+       struct nfs4_sequence_res        seq_res;
+       size_t                          xattr_len;
+};
+
+struct nfs42_listxattrsargs {
+       struct nfs4_sequence_args       seq_args;
+       struct nfs_fh                   *fh;
+       u32                             count;
+       u64                             cookie;
+       struct page                     **xattr_pages;
+};
+
+struct nfs42_listxattrsres {
+       struct nfs4_sequence_res        seq_res;
+       struct page                     *scratch;
+       void                            *xattr_buf;
+       size_t                          xattr_len;
+       u64                             cookie;
+       bool                            eof;
+       size_t                          copied;
+};
+
+struct nfs42_removexattrargs {
+       struct nfs4_sequence_args       seq_args;
+       struct nfs_fh                   *fh;
+       const char                      *xattr_name;
+};
+
+struct nfs42_removexattrres {
+       struct nfs4_sequence_res        seq_res;
+       struct nfs4_change_info         cinfo;
+};
+
+#endif /* CONFIG_NFS_V4_2 */
 
 struct nfs_page;
 
index d1f4eff..7de11dc 100644 (file)
@@ -381,7 +381,7 @@ static inline struct page *find_subpage(struct page *head, pgoff_t index)
        if (PageHuge(head))
                return head;
 
-       return head + (index & (hpage_nr_pages(head) - 1));
+       return head + (index & (thp_nr_pages(head) - 1));
 }
 
 struct page *find_get_entry(struct address_space *mapping, pgoff_t offset);
@@ -773,7 +773,7 @@ static inline struct page *readahead_page(struct readahead_control *rac)
 
        page = xa_load(&rac->mapping->i_pages, rac->_index);
        VM_BUG_ON_PAGE(!PageLocked(page), page);
-       rac->_batch_count = hpage_nr_pages(page);
+       rac->_batch_count = thp_nr_pages(page);
 
        return page;
 }
@@ -796,7 +796,7 @@ static inline unsigned int __readahead_batch(struct readahead_control *rac,
                VM_BUG_ON_PAGE(!PageLocked(page), page);
                VM_BUG_ON_PAGE(PageTail(page), page);
                array[i++] = page;
-               rac->_batch_count += hpage_nr_pages(page);
+               rac->_batch_count += thp_nr_pages(page);
 
                /*
                 * The page cache isn't using multi-index entries yet,
index a124c21..e8cbc2e 100644 (file)
@@ -117,7 +117,9 @@ static inline pgd_t *pgd_offset_pgd(pgd_t *pgd, unsigned long address)
  * a shortcut which implies the use of the kernel's pgd, instead
  * of a process's
  */
+#ifndef pgd_offset_k
 #define pgd_offset_k(address)          pgd_offset(&init_mm, (address))
+#endif
 
 /*
  * In many cases it is known that a virtual address is mapped at PMD or PTE
index a8e8763..c36fb41 100644 (file)
@@ -402,7 +402,8 @@ void pcs_get_state(struct phylink_pcs *pcs,
  * For most 10GBASE-R, there is no advertisement.
  */
 int pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-              phy_interface_t interface, const unsigned long *advertising);
+              phy_interface_t interface, const unsigned long *advertising,
+              bool permit_pause_to_mac);
 
 /**
  * pcs_an_restart() - restart 802.3z BaseX autonegotiation
diff --git a/include/linux/platform_data/clk-fch.h b/include/linux/platform_data/clk-fch.h
new file mode 100644 (file)
index 0000000..b9f6824
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * clock framework for AMD misc clocks
+ *
+ * Copyright 2018 Advanced Micro Devices, Inc.
+ */
+
+#ifndef __CLK_FCH_H
+#define __CLK_FCH_H
+
+#include <linux/compiler.h>
+
+struct fch_clk_data {
+       void __iomem *base;
+       u32 is_rv;
+};
+
+#endif /* __CLK_FCH_H */
diff --git a/include/linux/platform_data/clk-st.h b/include/linux/platform_data/clk-st.h
deleted file mode 100644 (file)
index 7cdb6a4..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-/*
- * clock framework for AMD Stoney based clock
- *
- * Copyright 2018 Advanced Micro Devices, Inc.
- */
-
-#ifndef __CLK_ST_H
-#define __CLK_ST_H
-
-#include <linux/compiler.h>
-
-struct st_clk_data {
-       void __iomem *base;
-};
-
-#endif /* __CLK_ST_H */
index e3f0f85..896c16d 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/list.h>
 #include <linux/alarmtimer.h>
 #include <linux/timerqueue.h>
+#include <linux/task_work.h>
 
 struct kernel_siginfo;
 struct task_struct;
@@ -125,6 +126,16 @@ struct posix_cputimers {
        unsigned int                    expiry_active;
 };
 
+/**
+ * posix_cputimers_work - Container for task work based posix CPU timer expiry
+ * @work:      The task work to be scheduled
+ * @scheduled:  @work has been scheduled already, no further processing
+ */
+struct posix_cputimers_work {
+       struct callback_head    work;
+       unsigned int            scheduled;
+};
+
 static inline void posix_cputimers_init(struct posix_cputimers *pct)
 {
        memset(pct, 0, sizeof(*pct));
@@ -165,6 +176,12 @@ static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
                                              u64 cpu_limit) { }
 #endif
 
+#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
+void posix_cputimers_init_work(void);
+#else
+static inline void posix_cputimers_init_work(void) { }
+#endif
+
 #define REQUEUE_PENDING 1
 
 /**
index 2635b2a..a13ff38 100644 (file)
@@ -39,7 +39,7 @@ enum pwm_polarity {
  * current PWM hardware state.
  */
 struct pwm_args {
-       unsigned int period;
+       u64 period;
        enum pwm_polarity polarity;
 };
 
@@ -56,8 +56,8 @@ enum {
  * @enabled: PWM enabled status
  */
 struct pwm_state {
-       unsigned int period;
-       unsigned int duty_cycle;
+       u64 period;
+       u64 duty_cycle;
        enum pwm_polarity polarity;
        bool enabled;
 };
@@ -107,13 +107,13 @@ static inline bool pwm_is_enabled(const struct pwm_device *pwm)
        return state.enabled;
 }
 
-static inline void pwm_set_period(struct pwm_device *pwm, unsigned int period)
+static inline void pwm_set_period(struct pwm_device *pwm, u64 period)
 {
        if (pwm)
                pwm->state.period = period;
 }
 
-static inline unsigned int pwm_get_period(const struct pwm_device *pwm)
+static inline u64 pwm_get_period(const struct pwm_device *pwm)
 {
        struct pwm_state state;
 
@@ -128,7 +128,7 @@ static inline void pwm_set_duty_cycle(struct pwm_device *pwm, unsigned int duty)
                pwm->state.duty_cycle = duty;
 }
 
-static inline unsigned int pwm_get_duty_cycle(const struct pwm_device *pwm)
+static inline u64 pwm_get_duty_cycle(const struct pwm_device *pwm)
 {
        struct pwm_state state;
 
index 53ddc02..93ecd93 100644 (file)
@@ -890,6 +890,10 @@ struct task_struct {
        /* Empty if CONFIG_POSIX_CPUTIMERS=n */
        struct posix_cputimers          posix_cputimers;
 
+#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
+       struct posix_cputimers_work     posix_cputimers_work;
+#endif
+
        /* Process credentials: */
 
        /* Tracer's credentials at attach: */
index 917d88e..a8ec3b6 100644 (file)
@@ -36,6 +36,9 @@ struct user_struct {
     defined(CONFIG_NET) || defined(CONFIG_IO_URING)
        atomic_long_t locked_vm;
 #endif
+#ifdef CONFIG_WATCH_QUEUE
+       atomic_t nr_watches;    /* The number of watches this user currently has */
+#endif
 
        /* Miscellaneous per-user rate limit */
        struct ratelimit_state ratelimit;
index e64bd82..a603d48 100644 (file)
@@ -101,6 +101,7 @@ struct rpc_rqst {
                                                         * used in the softirq.
                                                         */
        unsigned long           rq_majortimeo;  /* major timeout alarm */
+       unsigned long           rq_minortimeo;  /* minor timeout alarm */
        unsigned long           rq_timeout;     /* Current timeout value */
        ktime_t                 rq_rtt;         /* round-trip time */
        unsigned int            rq_retries;     /* # of retries */
index dc2b827..75ac7f8 100644 (file)
@@ -47,7 +47,6 @@ struct stat64;
 struct statfs;
 struct statfs64;
 struct statx;
-struct __sysctl_args;
 struct sysinfo;
 struct timespec;
 struct __kernel_old_timeval;
@@ -1117,7 +1116,6 @@ asmlinkage long sys_send(int, void __user *, size_t, unsigned);
 asmlinkage long sys_bdflush(int func, long data);
 asmlinkage long sys_oldumount(char __user *name);
 asmlinkage long sys_uselib(const char __user *library);
-asmlinkage long sys_sysctl(struct __sysctl_args __user *args);
 asmlinkage long sys_sysfs(int option,
                                unsigned long arg1, unsigned long arg2);
 asmlinkage long sys_fork(void);
index 50bb7f3..51298a4 100644 (file)
@@ -74,15 +74,13 @@ int proc_do_static_key(struct ctl_table *table, int write, void *buffer,
  * sysctl names can be mirrored automatically under /proc/sys.  The
  * procname supplied controls /proc naming.
  *
- * The table's mode will be honoured both for sys_sysctl(2) and
- * proc-fs access.
+ * The table's mode will be honoured for proc-fs access.
  *
  * Leaf nodes in the sysctl tree will be represented by a single file
  * under /proc; non-leaf nodes will be represented by directories.  A
  * null procname disables /proc mirroring at this node.
  *
- * sysctl(2) can automatically manage read and write requests through
- * the sysctl table.  The data and maxlen fields of the ctl_table
+ * The data and maxlen fields of the ctl_table
  * struct enable minimal validation of the values being written to be
  * performed, and the mode field allows minimal authentication.
  * 
index 75bee29..b8feba7 100644 (file)
@@ -43,7 +43,7 @@ static inline void *iscsit_priv_cmd(struct iscsi_cmd *cmd)
  * From iscsi_target_transport.c
  */
 
-extern int iscsit_register_transport(struct iscsit_transport *);
+extern void iscsit_register_transport(struct iscsit_transport *);
 extern void iscsit_unregister_transport(struct iscsit_transport *);
 extern struct iscsit_transport *iscsit_get_transport(int);
 extern void iscsit_put_transport(struct iscsit_transport *);
index 7bcc8cd..3afe376 100644 (file)
@@ -56,6 +56,7 @@
 #define NFSDBG_PNFS            0x1000
 #define NFSDBG_PNFS_LD         0x2000
 #define NFSDBG_STATE           0x4000
+#define NFSDBG_XATTRCACHE      0x8000
 #define NFSDBG_ALL             0xFFFF
 
 
index ee810ca..73eb622 100644 (file)
 #include <vdso/time32.h>
 #include <vdso/time64.h>
 
+#ifdef CONFIG_ARCH_HAS_VDSO_DATA
+#include <asm/vdso/data.h>
+#else
+struct arch_vdso_data {};
+#endif
+
 #define VDSO_BASES     (CLOCK_TAI + 1)
 #define VDSO_HRES      (BIT(CLOCK_REALTIME)            | \
                         BIT(CLOCK_MONOTONIC)           | \
@@ -64,6 +70,8 @@ struct vdso_timestamp {
  * @tz_dsttime:                type of DST correction
  * @hrtimer_res:       hrtimer resolution
  * @__unused:          unused
+ * @arch_data:         architecture specific data (optional, defaults
+ *                     to an empty struct)
  *
  * vdso_data will be accessed by 64 bit and compat code at the same time
  * so we should be careful before modifying this structure.
@@ -97,6 +105,8 @@ struct vdso_data {
        s32                     tz_dsttime;
        u32                     hrtimer_res;
        u32                     __unused;
+
+       struct arch_vdso_data   arch_data;
 };
 
 /*
index 2c6134e..b0fdc9c 100644 (file)
@@ -6,6 +6,9 @@
 
 #include <asm/vdso/vsyscall.h>
 
+unsigned long vdso_update_begin(void);
+void vdso_update_end(unsigned long flags);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __VDSO_VSYSCALL_H */
index fdc279d..d43ca03 100644 (file)
@@ -38,7 +38,8 @@
  *                           Protocol version
  ******************************************************************************
  */
-#define XENDISPL_PROTOCOL_VERSION      "1"
+#define XENDISPL_PROTOCOL_VERSION      "2"
+#define XENDISPL_PROTOCOL_VERSION_INT   2
 
 /*
  ******************************************************************************
  *      Width and height of the connector in pixels separated by
  *      XENDISPL_RESOLUTION_SEPARATOR. This defines visible area of the
  *      display.
+ *      If backend provides extended display identification data (EDID) with
+ *      XENDISPL_OP_GET_EDID request then EDID values must take precedence
+ *      over the resolutions defined here.
  *
  *------------------ Connector Request Transport Parameters -------------------
  *
 #define XENDISPL_OP_FB_DETACH          0x13
 #define XENDISPL_OP_SET_CONFIG         0x14
 #define XENDISPL_OP_PG_FLIP            0x15
+/* The below command is available in protocol version 2 and above. */
+#define XENDISPL_OP_GET_EDID           0x16
 
 /*
  ******************************************************************************
 #define XENDISPL_FIELD_BE_ALLOC                "be-alloc"
 #define XENDISPL_FIELD_UNIQUE_ID       "unique-id"
 
+#define XENDISPL_EDID_BLOCK_SIZE       128
+#define XENDISPL_EDID_BLOCK_COUNT      256
+#define XENDISPL_EDID_MAX_SIZE         (XENDISPL_EDID_BLOCK_SIZE * XENDISPL_EDID_BLOCK_COUNT)
+
 /*
  ******************************************************************************
  *                          STATUS RETURN CODES
  * +----------------+----------------+----------------+----------------+
  * |                           gref_directory                          | 40
  * +----------------+----------------+----------------+----------------+
- * |                             reserved                              | 44
+ * |                             data_ofs                              | 44
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 48
  * +----------------+----------------+----------------+----------------+
  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
  * +----------------+----------------+----------------+----------------+
  *   buffer size (buffer_sz) exceeds what can be addressed by this single page,
  *   then reference to the next page must be supplied (see gref_dir_next_page
  *   below)
+ * data_ofs - uint32_t, offset of the data in the buffer, octets
  */
 
 #define XENDISPL_DBUF_FLG_REQ_ALLOC    (1 << 0)
@@ -506,6 +519,7 @@ struct xendispl_dbuf_create_req {
        uint32_t buffer_sz;
        uint32_t flags;
        grant_ref_t gref_directory;
+       uint32_t data_ofs;
 };
 
 /*
@@ -731,6 +745,44 @@ struct xendispl_page_flip_req {
        uint64_t fb_cookie;
 };
 
+/*
+ * Request EDID - request EDID describing current connector:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                | _OP_GET_EDID   |   reserved     | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                             buffer_sz                             | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                          gref_directory                           | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Notes:
+ *   - This command is not available in protocol version 1 and should be
+ *     ignored.
+ *   - This request is optional and if not supported then visible area
+ *     is defined by the relevant XenStore's "resolution" property.
+ *   - Shared buffer, allocated for EDID storage, must not be less then
+ *     XENDISPL_EDID_MAX_SIZE octets.
+ *
+ * buffer_sz - uint32_t, buffer size to be allocated, octets
+ * gref_directory - grant_ref_t, a reference to the first shared page
+ *   describing EDID buffer references. See XENDISPL_OP_DBUF_CREATE for
+ *   grant page directory structure (struct xendispl_page_directory).
+ *
+ * See response format for this request.
+ */
+
+struct xendispl_get_edid_req {
+       uint32_t buffer_sz;
+       grant_ref_t gref_directory;
+};
+
 /*
  *---------------------------------- Responses --------------------------------
  *
@@ -753,6 +805,35 @@ struct xendispl_page_flip_req {
  * id - uint16_t, private guest value, echoed from request
  * status - int32_t, response status, zero on success and -XEN_EXX on failure
  *
+ *
+ * Get EDID response - response for XENDISPL_OP_GET_EDID:
+ *         0                1                 2               3        octet
+ * +----------------+----------------+----------------+----------------+
+ * |               id                |    operation   |    reserved    | 4
+ * +----------------+----------------+----------------+----------------+
+ * |                              status                               | 8
+ * +----------------+----------------+----------------+----------------+
+ * |                             edid_sz                               | 12
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 16
+ * +----------------+----------------+----------------+----------------+
+ * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
+ * +----------------+----------------+----------------+----------------+
+ * |                             reserved                              | 64
+ * +----------------+----------------+----------------+----------------+
+ *
+ * Notes:
+ *   - This response is not available in protocol version 1 and should be
+ *     ignored.
+ *
+ * edid_sz - uint32_t, size of the EDID, octets
+ */
+
+struct xendispl_get_edid_resp {
+       uint32_t edid_sz;
+};
+
+/*
  *----------------------------------- Events ----------------------------------
  *
  * Events are sent via a shared page allocated by the front and propagated by
@@ -804,6 +885,7 @@ struct xendispl_req {
                struct xendispl_fb_detach_req fb_detach;
                struct xendispl_set_config_req set_config;
                struct xendispl_page_flip_req pg_flip;
+               struct xendispl_get_edid_req get_edid;
                uint8_t reserved[56];
        } op;
 };
@@ -813,7 +895,10 @@ struct xendispl_resp {
        uint8_t operation;
        uint8_t reserved;
        int32_t status;
-       uint8_t reserved1[56];
+       union {
+               struct xendispl_get_edid_resp get_edid;
+               uint8_t reserved1[56];
+       } op;
 };
 
 struct xendispl_evt {
index 89024e8..f6889fc 100644 (file)
@@ -65,6 +65,7 @@ struct task_struct init_task
 #ifdef CONFIG_ARCH_TASK_STRUCT_ON_STACK
        __init_task_data
 #endif
+       __aligned(L1_CACHE_BYTES)
 = {
 #ifdef CONFIG_THREAD_INFO_IN_TASK
        .thread_info    = INIT_THREAD_INFO(init_task),
index b3da548..9a20016 100644 (file)
@@ -5,7 +5,7 @@
 
 obj-y     = fork.o exec_domain.o panic.o \
            cpu.o exit.o softirq.o resource.o \
-           sysctl.o sysctl_binary.o capability.o ptrace.o user.o \
+           sysctl.o capability.o ptrace.o user.o \
            signal.o sys.o umh.o workqueue.o pid.o task_work.o \
            extable.o params.o \
            kthread.o sys_ni.o nsproxy.o \
index 4fd830a..cfed0ac 100644 (file)
@@ -213,11 +213,13 @@ static int stack_map_get_build_id_32(void *page_addr,
 
        phdr = (Elf32_Phdr *)(page_addr + sizeof(Elf32_Ehdr));
 
-       for (i = 0; i < ehdr->e_phnum; ++i)
-               if (phdr[i].p_type == PT_NOTE)
-                       return stack_map_parse_build_id(page_addr, build_id,
-                                       page_addr + phdr[i].p_offset,
-                                       phdr[i].p_filesz);
+       for (i = 0; i < ehdr->e_phnum; ++i) {
+               if (phdr[i].p_type == PT_NOTE &&
+                   !stack_map_parse_build_id(page_addr, build_id,
+                                             page_addr + phdr[i].p_offset,
+                                             phdr[i].p_filesz))
+                       return 0;
+       }
        return -EINVAL;
 }
 
@@ -236,11 +238,13 @@ static int stack_map_get_build_id_64(void *page_addr,
 
        phdr = (Elf64_Phdr *)(page_addr + sizeof(Elf64_Ehdr));
 
-       for (i = 0; i < ehdr->e_phnum; ++i)
-               if (phdr[i].p_type == PT_NOTE)
-                       return stack_map_parse_build_id(page_addr, build_id,
-                                       page_addr + phdr[i].p_offset,
-                                       phdr[i].p_filesz);
+       for (i = 0; i < ehdr->e_phnum; ++i) {
+               if (phdr[i].p_type == PT_NOTE &&
+                   !stack_map_parse_build_id(page_addr, build_id,
+                                             page_addr + phdr[i].p_offset,
+                                             phdr[i].p_filesz))
+                       return 0;
+       }
        return -EINVAL;
 }
 
index f4770fc..847a9d1 100644 (file)
@@ -1,5 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
+config NO_DMA
+       bool
+
 config HAS_DMA
        bool
        depends on !NO_DMA
@@ -186,11 +189,6 @@ config DMA_API_DEBUG
          drivers like double-freeing of DMA mappings or freeing mappings that
          were never allocated.
 
-         This also attempts to catch cases where a page owned by DMA is
-         accessed by the cpu in a way that could cause data corruption.  For
-         example, this enables cow_user_page() to check that the source page is
-         not undergoing DMA.
-
          This option causes a performance degradation.  Use only if you want to
          debug device drivers and dma interactions.
 
index f7f807f..8e9f7b3 100644 (file)
@@ -448,9 +448,6 @@ void debug_dma_dump_mappings(struct device *dev)
  * dma_active_cacheline entry to track per event.  dma_map_sg(), on the
  * other hand, consumes a single dma_debug_entry, but inserts 'nents'
  * entries into the tree.
- *
- * At any time debug_dma_assert_idle() can be called to trigger a
- * warning if any cachelines in the given page are in the active set.
  */
 static RADIX_TREE(dma_active_cacheline, GFP_NOWAIT);
 static DEFINE_SPINLOCK(radix_lock);
@@ -497,10 +494,7 @@ static void active_cacheline_inc_overlap(phys_addr_t cln)
        overlap = active_cacheline_set_overlap(cln, ++overlap);
 
        /* If we overflowed the overlap counter then we're potentially
-        * leaking dma-mappings.  Otherwise, if maps and unmaps are
-        * balanced then this overflow may cause false negatives in
-        * debug_dma_assert_idle() as the cacheline may be marked idle
-        * prematurely.
+        * leaking dma-mappings.
         */
        WARN_ONCE(overlap > ACTIVE_CACHELINE_MAX_OVERLAP,
                  pr_fmt("exceeded %d overlapping mappings of cacheline %pa\n"),
@@ -555,53 +549,6 @@ static void active_cacheline_remove(struct dma_debug_entry *entry)
        spin_unlock_irqrestore(&radix_lock, flags);
 }
 
-/**
- * debug_dma_assert_idle() - assert that a page is not undergoing dma
- * @page: page to lookup in the dma_active_cacheline tree
- *
- * Place a call to this routine in cases where the cpu touching the page
- * before the dma completes (page is dma_unmapped) will lead to data
- * corruption.
- */
-void debug_dma_assert_idle(struct page *page)
-{
-       static struct dma_debug_entry *ents[CACHELINES_PER_PAGE];
-       struct dma_debug_entry *entry = NULL;
-       void **results = (void **) &ents;
-       unsigned int nents, i;
-       unsigned long flags;
-       phys_addr_t cln;
-
-       if (dma_debug_disabled())
-               return;
-
-       if (!page)
-               return;
-
-       cln = (phys_addr_t) page_to_pfn(page) << CACHELINE_PER_PAGE_SHIFT;
-       spin_lock_irqsave(&radix_lock, flags);
-       nents = radix_tree_gang_lookup(&dma_active_cacheline, results, cln,
-                                      CACHELINES_PER_PAGE);
-       for (i = 0; i < nents; i++) {
-               phys_addr_t ent_cln = to_cacheline_number(ents[i]);
-
-               if (ent_cln == cln) {
-                       entry = ents[i];
-                       break;
-               } else if (ent_cln >= cln + CACHELINES_PER_PAGE)
-                       break;
-       }
-       spin_unlock_irqrestore(&radix_lock, flags);
-
-       if (!entry)
-               return;
-
-       cln = to_cacheline_number(entry);
-       err_printk(entry->dev, entry,
-                  "cpu touching an active dma mapped cacheline [cln=%pa]\n",
-                  &cln);
-}
-
 /*
  * Wrapper function for adding an entry to the hash.
  * This function takes care of locking itself.
index 6961333..5bfe8e3 100644 (file)
@@ -11706,7 +11706,7 @@ SYSCALL_DEFINE5(perf_event_open,
                        goto err_task;
 
                /*
-                * Reuse ptrace permission checks for now.
+                * Preserve ptrace permission check for backwards compatibility.
                 *
                 * We must hold exec_update_mutex across this and any potential
                 * perf_install_in_context() call for this new event to
@@ -11714,7 +11714,7 @@ SYSCALL_DEFINE5(perf_event_open,
                 * perf_event_exit_task() that could imply).
                 */
                err = -EACCES;
-               if (!ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
+               if (!perfmon_capable() && !ptrace_may_access(task, PTRACE_MODE_READ_REALCREDS))
                        goto err_cred;
        }
 
index 61e8153..a587669 100644 (file)
@@ -3744,12 +3744,12 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,
        switch (cmd) {
        case FUTEX_WAIT:
                val3 = FUTEX_BITSET_MATCH_ANY;
-               /* fall through */
+               fallthrough;
        case FUTEX_WAIT_BITSET:
                return futex_wait(uaddr, flags, val, timeout, val3);
        case FUTEX_WAKE:
                val3 = FUTEX_BITSET_MATCH_ANY;
-               /* fall through */
+               fallthrough;
        case FUTEX_WAKE_BITSET:
                return futex_wake(uaddr, flags, val, val3);
        case FUTEX_REQUEUE:
index d55ba62..52ac539 100644 (file)
@@ -2731,8 +2731,10 @@ int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
 
        do {
                chip = irq_data_get_irq_chip(data);
-               if (WARN_ON_ONCE(!chip))
-                       return -ENODEV;
+               if (WARN_ON_ONCE(!chip)) {
+                       err = -ENODEV;
+                       goto out_unlock;
+               }
                if (chip->irq_set_irqchip_state)
                        break;
 #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
@@ -2745,6 +2747,7 @@ int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
        if (data)
                err = chip->irq_set_irqchip_state(data, which, val);
 
+out_unlock:
        irq_put_desc_busunlock(desc, flags);
        return err;
 }
index 8f557fa..c6c7e18 100644 (file)
@@ -185,14 +185,18 @@ void rearm_wake_irq(unsigned int irq)
        unsigned long flags;
        struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
 
-       if (!desc || !(desc->istate & IRQS_SUSPENDED) ||
-           !irqd_is_wakeup_set(&desc->irq_data))
+       if (!desc)
                return;
 
+       if (!(desc->istate & IRQS_SUSPENDED) ||
+           !irqd_is_wakeup_set(&desc->irq_data))
+               goto unlock;
+
        desc->istate &= ~IRQS_SUSPENDED;
        irqd_set(&desc->irq_data, IRQD_WAKEUP_ARMED);
        __enable_irq(desc);
 
+unlock:
        irq_put_desc_busunlock(desc, flags);
 }
 
index 78c0837..ca40bef 100644 (file)
@@ -1169,24 +1169,26 @@ int crash_exclude_mem_range(struct crash_mem *mem,
                            unsigned long long mstart, unsigned long long mend)
 {
        int i, j;
-       unsigned long long start, end;
+       unsigned long long start, end, p_start, p_end;
        struct crash_mem_range temp_range = {0, 0};
 
        for (i = 0; i < mem->nr_ranges; i++) {
                start = mem->ranges[i].start;
                end = mem->ranges[i].end;
+               p_start = mstart;
+               p_end = mend;
 
                if (mstart > end || mend < start)
                        continue;
 
                /* Truncate any area outside of range */
                if (mstart < start)
-                       mstart = start;
+                       p_start = start;
                if (mend > end)
-                       mend = end;
+                       p_end = end;
 
                /* Found completely overlapping range */
-               if (mstart == start && mend == end) {
+               if (p_start == start && p_end == end) {
                        mem->ranges[i].start = 0;
                        mem->ranges[i].end = 0;
                        if (i < mem->nr_ranges - 1) {
@@ -1197,20 +1199,29 @@ int crash_exclude_mem_range(struct crash_mem *mem,
                                        mem->ranges[j].end =
                                                        mem->ranges[j+1].end;
                                }
+
+                               /*
+                                * Continue to check if there are another overlapping ranges
+                                * from the current position because of shifting the above
+                                * mem ranges.
+                                */
+                               i--;
+                               mem->nr_ranges--;
+                               continue;
                        }
                        mem->nr_ranges--;
                        return 0;
                }
 
-               if (mstart > start && mend < end) {
+               if (p_start > start && p_end < end) {
                        /* Split original range */
-                       mem->ranges[i].end = mstart - 1;
-                       temp_range.start = mend + 1;
+                       mem->ranges[i].end = p_start - 1;
+                       temp_range.start = p_end + 1;
                        temp_range.end = end;
-               } else if (mstart != start)
-                       mem->ranges[i].end = mstart - 1;
+               } else if (p_start != start)
+                       mem->ranges[i].end = p_start - 1;
                else
-                       mem->ranges[i].start = mend + 1;
+                       mem->ranges[i].start = p_end + 1;
                break;
        }
 
@@ -1247,7 +1258,7 @@ int crash_prepare_elf64_headers(struct crash_mem *mem, int kernel_map,
        unsigned long long notes_addr;
        unsigned long mstart, mend;
 
-       /* extra phdr for vmcoreinfo elf note */
+       /* extra phdr for vmcoreinfo ELF note */
        nr_phdr = nr_cpus + 1;
        nr_phdr += mem->nr_ranges;
 
@@ -1255,7 +1266,7 @@ int crash_prepare_elf64_headers(struct crash_mem *mem, int kernel_map,
         * kexec-tools creates an extra PT_LOAD phdr for kernel text mapping
         * area (for example, ffffffff80000000 - ffffffffa0000000 on x86_64).
         * I think this is required by tools like gdb. So same physical
-        * memory will be mapped in two elf headers. One will contain kernel
+        * memory will be mapped in two ELF headers. One will contain kernel
         * text virtual addresses and other will have __va(physical) addresses.
         */
 
@@ -1282,7 +1293,7 @@ int crash_prepare_elf64_headers(struct crash_mem *mem, int kernel_map,
        ehdr->e_ehsize = sizeof(Elf64_Ehdr);
        ehdr->e_phentsize = sizeof(Elf64_Phdr);
 
-       /* Prepare one phdr of type PT_NOTE for each present cpu */
+       /* Prepare one phdr of type PT_NOTE for each present CPU */
        for_each_present_cpu(cpu) {
                phdr->p_type = PT_NOTE;
                notes_addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpu));
@@ -1324,10 +1335,10 @@ int crash_prepare_elf64_headers(struct crash_mem *mem, int kernel_map,
                phdr->p_filesz = phdr->p_memsz = mend - mstart + 1;
                phdr->p_align = 0;
                ehdr->e_phnum++;
-               phdr++;
-               pr_debug("Crash PT_LOAD elf header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n",
+               pr_debug("Crash PT_LOAD ELF header. phdr=%p vaddr=0x%llx, paddr=0x%llx, sz=0x%llx e_phnum=%d p_offset=0x%llx\n",
                        phdr, phdr->p_vaddr, phdr->p_paddr, phdr->p_filesz,
                        ehdr->e_phnum, phdr->p_offset);
+               phdr++;
        }
 
        *addr = buf;
index 8fa2600..1c5cff3 100644 (file)
@@ -422,7 +422,7 @@ static bool each_symbol_in_section(const struct symsearch *arr,
 }
 
 /* Returns true as soon as fn returns true, otherwise false. */
-bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
+static bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
                                    struct module *owner,
                                    void *data),
                         void *data)
@@ -484,7 +484,6 @@ bool each_symbol_section(bool (*fn)(const struct symsearch *arr,
        }
        return false;
 }
-EXPORT_SYMBOL_GPL(each_symbol_section);
 
 struct find_symbol_arg {
        /* Input */
@@ -496,6 +495,7 @@ struct find_symbol_arg {
        struct module *owner;
        const s32 *crc;
        const struct kernel_symbol *sym;
+       enum mod_license license;
 };
 
 static bool check_exported_symbol(const struct symsearch *syms,
@@ -505,9 +505,9 @@ static bool check_exported_symbol(const struct symsearch *syms,
        struct find_symbol_arg *fsa = data;
 
        if (!fsa->gplok) {
-               if (syms->licence == GPL_ONLY)
+               if (syms->license == GPL_ONLY)
                        return false;
-               if (syms->licence == WILL_BE_GPL_ONLY && fsa->warn) {
+               if (syms->license == WILL_BE_GPL_ONLY && fsa->warn) {
                        pr_warn("Symbol %s is being used by a non-GPL module, "
                                "which will not be allowed in the future\n",
                                fsa->name);
@@ -529,6 +529,7 @@ static bool check_exported_symbol(const struct symsearch *syms,
        fsa->owner = owner;
        fsa->crc = symversion(syms->crcs, symnum);
        fsa->sym = &syms->start[symnum];
+       fsa->license = syms->license;
        return true;
 }
 
@@ -585,9 +586,10 @@ static bool find_exported_symbol_in_section(const struct symsearch *syms,
 
 /* Find an exported symbol and return it, along with, (optional) crc and
  * (optional) module which owns it.  Needs preempt disabled or module_mutex. */
-const struct kernel_symbol *find_symbol(const char *name,
+static const struct kernel_symbol *find_symbol(const char *name,
                                        struct module **owner,
                                        const s32 **crc,
+                                       enum mod_license *license,
                                        bool gplok,
                                        bool warn)
 {
@@ -602,13 +604,14 @@ const struct kernel_symbol *find_symbol(const char *name,
                        *owner = fsa.owner;
                if (crc)
                        *crc = fsa.crc;
+               if (license)
+                       *license = fsa.license;
                return fsa.sym;
        }
 
        pr_debug("Failed to find symbol %s\n", name);
        return NULL;
 }
-EXPORT_SYMBOL_GPL(find_symbol);
 
 /*
  * Search for module by name: must hold module_mutex (or preempt disabled
@@ -869,7 +872,7 @@ static int add_module_usage(struct module *a, struct module *b)
 }
 
 /* Module a uses b: caller needs module_mutex() */
-int ref_module(struct module *a, struct module *b)
+static int ref_module(struct module *a, struct module *b)
 {
        int err;
 
@@ -888,7 +891,6 @@ int ref_module(struct module *a, struct module *b)
        }
        return 0;
 }
-EXPORT_SYMBOL_GPL(ref_module);
 
 /* Clear the unload stuff of the module. */
 static void module_unload_free(struct module *mod)
@@ -1077,7 +1079,7 @@ void __symbol_put(const char *symbol)
        struct module *owner;
 
        preempt_disable();
-       if (!find_symbol(symbol, &owner, NULL, true, false))
+       if (!find_symbol(symbol, &owner, NULL, NULL, true, false))
                BUG();
        module_put(owner);
        preempt_enable();
@@ -1169,11 +1171,10 @@ static inline void module_unload_free(struct module *mod)
 {
 }
 
-int ref_module(struct module *a, struct module *b)
+static int ref_module(struct module *a, struct module *b)
 {
        return strong_try_module_get(b);
 }
-EXPORT_SYMBOL_GPL(ref_module);
 
 static inline int module_unload_init(struct module *mod)
 {
@@ -1356,7 +1357,7 @@ static inline int check_modstruct_version(const struct load_info *info,
         * locking is necessary -- use preempt_disable() to placate lockdep.
         */
        preempt_disable();
-       if (!find_symbol("module_layout", NULL, &crc, true, false)) {
+       if (!find_symbol("module_layout", NULL, &crc, NULL, true, false)) {
                preempt_enable();
                BUG();
        }
@@ -1430,6 +1431,24 @@ static int verify_namespace_is_imported(const struct load_info *info,
        return 0;
 }
 
+static bool inherit_taint(struct module *mod, struct module *owner)
+{
+       if (!owner || !test_bit(TAINT_PROPRIETARY_MODULE, &owner->taints))
+               return true;
+
+       if (mod->using_gplonly_symbols) {
+               pr_err("%s: module using GPL-only symbols uses symbols from proprietary module %s.\n",
+                       mod->name, owner->name);
+               return false;
+       }
+
+       if (!test_bit(TAINT_PROPRIETARY_MODULE, &mod->taints)) {
+               pr_warn("%s: module uses symbols from proprietary module %s, inheriting taint.\n",
+                       mod->name, owner->name);
+               set_bit(TAINT_PROPRIETARY_MODULE, &mod->taints);
+       }
+       return true;
+}
 
 /* Resolve a symbol for this module.  I.e. if we find one, record usage. */
 static const struct kernel_symbol *resolve_symbol(struct module *mod,
@@ -1440,6 +1459,7 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
        struct module *owner;
        const struct kernel_symbol *sym;
        const s32 *crc;
+       enum mod_license license;
        int err;
 
        /*
@@ -1449,11 +1469,19 @@ static const struct kernel_symbol *resolve_symbol(struct module *mod,
         */
        sched_annotate_sleep();
        mutex_lock(&module_mutex);
-       sym = find_symbol(name, &owner, &crc,
+       sym = find_symbol(name, &owner, &crc, &license,
                          !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
        if (!sym)
                goto unlock;
 
+       if (license == GPL_ONLY)
+               mod->using_gplonly_symbols = true;
+
+       if (!inherit_taint(mod, owner)) {
+               sym = NULL;
+               goto getname;
+       }
+
        if (!check_version(info, name, mod, crc)) {
                sym = ERR_PTR(-EINVAL);
                goto getname;
@@ -2236,7 +2264,7 @@ void *__symbol_get(const char *symbol)
        const struct kernel_symbol *sym;
 
        preempt_disable();
-       sym = find_symbol(symbol, &owner, NULL, true, true);
+       sym = find_symbol(symbol, &owner, NULL, NULL, true, true);
        if (sym && strong_try_module_get(owner))
                sym = NULL;
        preempt_enable();
@@ -2272,7 +2300,7 @@ static int verify_exported_symbols(struct module *mod)
        for (i = 0; i < ARRAY_SIZE(arr); i++) {
                for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
                        if (find_symbol(kernel_symbol_name(s), &owner, NULL,
-                                       true, false)) {
+                                       NULL, true, false)) {
                                pr_err("%s: exports duplicate symbol %s"
                                       " (owned by %s)\n",
                                       mod->name, kernel_symbol_name(s),
@@ -4489,7 +4517,6 @@ struct module *__module_address(unsigned long addr)
        }
        return mod;
 }
-EXPORT_SYMBOL_GPL(__module_address);
 
 /*
  * is_module_text_address - is this address inside module code?
@@ -4528,7 +4555,6 @@ struct module *__module_text_address(unsigned long addr)
        }
        return mod;
 }
-EXPORT_SYMBOL_GPL(__module_text_address);
 
 /* Don't grab lock, we're oopsing. */
 void print_modules(void)
index 84758f3..8471a0f 100644 (file)
@@ -6431,10 +6431,10 @@ void sched_show_task(struct task_struct *p)
        if (!try_get_task_stack(p))
                return;
 
-       printk(KERN_INFO "%-15.15s %c", p->comm, task_state_to_char(p));
+       pr_info("task:%-15.15s state:%c", p->comm, task_state_to_char(p));
 
        if (p->state == TASK_RUNNING)
-               printk(KERN_CONT "  running task    ");
+               pr_cont("  running task    ");
 #ifdef CONFIG_DEBUG_STACK_USAGE
        free = stack_not_used(p);
 #endif
@@ -6443,8 +6443,8 @@ void sched_show_task(struct task_struct *p)
        if (pid_alive(p))
                ppid = task_pid_nr(rcu_dereference(p->real_parent));
        rcu_read_unlock();
-       printk(KERN_CONT "%5lu %5d %6d 0x%08lx\n", free,
-               task_pid_nr(p), ppid,
+       pr_cont(" stack:%5lu pid:%5d ppid:%6d flags:0x%08lx\n",
+               free, task_pid_nr(p), ppid,
                (unsigned long)task_thread_info(p)->flags);
 
        print_worker_info(KERN_INFO, p);
@@ -6479,13 +6479,6 @@ void show_state_filter(unsigned long state_filter)
 {
        struct task_struct *g, *p;
 
-#if BITS_PER_LONG == 32
-       printk(KERN_INFO
-               "  task                PC stack   pid father\n");
-#else
-       printk(KERN_INFO
-               "  task                        PC stack   pid father\n");
-#endif
        rcu_read_lock();
        for_each_process_thread(g, p) {
                /*
index 3fd2838..28709f6 100644 (file)
@@ -1999,7 +1999,7 @@ static inline void sub_nr_running(struct rq *rq, unsigned count)
 {
        rq->nr_running -= count;
        if (trace_sched_update_nr_running_tp_enabled()) {
-               call_trace_sched_update_nr_running(rq, count);
+               call_trace_sched_update_nr_running(rq, -count);
        }
 
        /* Check if we still need preemption */
index 6f16f7c..42b67d2 100644 (file)
@@ -2541,7 +2541,21 @@ bool get_signal(struct ksignal *ksig)
 
 relock:
        spin_lock_irq(&sighand->siglock);
-       current->jobctl &= ~JOBCTL_TASK_WORK;
+       /*
+        * Make sure we can safely read ->jobctl() in task_work add. As Oleg
+        * states:
+        *
+        * It pairs with mb (implied by cmpxchg) before READ_ONCE. So we
+        * roughly have
+        *
+        *      task_work_add:                          get_signal:
+        *      STORE(task->task_works, new_work);      STORE(task->jobctl);
+        *      mb();                                   mb();
+        *      LOAD(task->jobctl);                     LOAD(task->task_works);
+        *
+        * and we can rely on STORE-MB-LOAD [ in task_work_add].
+        */
+       smp_store_mb(current->jobctl, current->jobctl & ~JOBCTL_TASK_WORK);
        if (unlikely(current->task_works)) {
                spin_unlock_irq(&sighand->siglock);
                task_work_run();
index 3b69a56..4d59775 100644 (file)
@@ -364,7 +364,6 @@ COND_SYSCALL(socketcall);
 COND_SYSCALL_COMPAT(socketcall);
 
 /* compat syscalls for arm64, x86, ... */
-COND_SYSCALL_COMPAT(sysctl);
 COND_SYSCALL_COMPAT(fanotify_mark);
 
 /* x86 */
diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c
deleted file mode 100644 (file)
index 7d550cc..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <linux/stat.h>
-#include <linux/sysctl.h>
-#include "../fs/xfs/xfs_sysctl.h"
-#include <linux/sunrpc/debug.h>
-#include <linux/string.h>
-#include <linux/syscalls.h>
-#include <linux/namei.h>
-#include <linux/mount.h>
-#include <linux/fs.h>
-#include <linux/nsproxy.h>
-#include <linux/pid_namespace.h>
-#include <linux/file.h>
-#include <linux/ctype.h>
-#include <linux/netdevice.h>
-#include <linux/kernel.h>
-#include <linux/uuid.h>
-#include <linux/slab.h>
-#include <linux/compat.h>
-
-static ssize_t binary_sysctl(const int *name, int nlen,
-       void __user *oldval, size_t oldlen, void __user *newval, size_t newlen)
-{
-       return -ENOSYS;
-}
-
-static void deprecated_sysctl_warning(const int *name, int nlen)
-{
-       int i;
-
-       /*
-        * CTL_KERN/KERN_VERSION is used by older glibc and cannot
-        * ever go away.
-        */
-       if (nlen >= 2 && name[0] == CTL_KERN && name[1] == KERN_VERSION)
-               return;
-
-       if (printk_ratelimit()) {
-               printk(KERN_INFO
-                       "warning: process `%s' used the deprecated sysctl "
-                       "system call with ", current->comm);
-               for (i = 0; i < nlen; i++)
-                       printk(KERN_CONT "%d.", name[i]);
-               printk(KERN_CONT "\n");
-       }
-       return;
-}
-
-#define WARN_ONCE_HASH_BITS 8
-#define WARN_ONCE_HASH_SIZE (1<<WARN_ONCE_HASH_BITS)
-
-static DECLARE_BITMAP(warn_once_bitmap, WARN_ONCE_HASH_SIZE);
-
-#define FNV32_OFFSET 2166136261U
-#define FNV32_PRIME 0x01000193
-
-/*
- * Print each legacy sysctl (approximately) only once.
- * To avoid making the tables non-const use a external
- * hash-table instead.
- * Worst case hash collision: 6, but very rarely.
- * NOTE! We don't use the SMP-safe bit tests. We simply
- * don't care enough.
- */
-static void warn_on_bintable(const int *name, int nlen)
-{
-       int i;
-       u32 hash = FNV32_OFFSET;
-
-       for (i = 0; i < nlen; i++)
-               hash = (hash ^ name[i]) * FNV32_PRIME;
-       hash %= WARN_ONCE_HASH_SIZE;
-       if (__test_and_set_bit(hash, warn_once_bitmap))
-               return;
-       deprecated_sysctl_warning(name, nlen);
-}
-
-static ssize_t do_sysctl(int __user *args_name, int nlen,
-       void __user *oldval, size_t oldlen, void __user *newval, size_t newlen)
-{
-       int name[CTL_MAXNAME];
-       int i;
-
-       /* Check args->nlen. */
-       if (nlen < 0 || nlen > CTL_MAXNAME)
-               return -ENOTDIR;
-       /* Read in the sysctl name for simplicity */
-       for (i = 0; i < nlen; i++)
-               if (get_user(name[i], args_name + i))
-                       return -EFAULT;
-
-       warn_on_bintable(name, nlen);
-
-       return binary_sysctl(name, nlen, oldval, oldlen, newval, newlen);
-}
-
-SYSCALL_DEFINE1(sysctl, struct __sysctl_args __user *, args)
-{
-       struct __sysctl_args tmp;
-       size_t oldlen = 0;
-       ssize_t result;
-
-       if (copy_from_user(&tmp, args, sizeof(tmp)))
-               return -EFAULT;
-
-       if (tmp.oldval && !tmp.oldlenp)
-               return -EFAULT;
-
-       if (tmp.oldlenp && get_user(oldlen, tmp.oldlenp))
-               return -EFAULT;
-
-       result = do_sysctl(tmp.name, tmp.nlen, tmp.oldval, oldlen,
-                          tmp.newval, tmp.newlen);
-
-       if (result >= 0) {
-               oldlen = result;
-               result = 0;
-       }
-
-       if (tmp.oldlenp && put_user(oldlen, tmp.oldlenp))
-               return -EFAULT;
-
-       return result;
-}
-
-
-#ifdef CONFIG_COMPAT
-
-struct compat_sysctl_args {
-       compat_uptr_t   name;
-       int             nlen;
-       compat_uptr_t   oldval;
-       compat_uptr_t   oldlenp;
-       compat_uptr_t   newval;
-       compat_size_t   newlen;
-       compat_ulong_t  __unused[4];
-};
-
-COMPAT_SYSCALL_DEFINE1(sysctl, struct compat_sysctl_args __user *, args)
-{
-       struct compat_sysctl_args tmp;
-       compat_size_t __user *compat_oldlenp;
-       size_t oldlen = 0;
-       ssize_t result;
-
-       if (copy_from_user(&tmp, args, sizeof(tmp)))
-               return -EFAULT;
-
-       if (tmp.oldval && !tmp.oldlenp)
-               return -EFAULT;
-
-       compat_oldlenp = compat_ptr(tmp.oldlenp);
-       if (compat_oldlenp && get_user(oldlen, compat_oldlenp))
-               return -EFAULT;
-
-       result = do_sysctl(compat_ptr(tmp.name), tmp.nlen,
-                          compat_ptr(tmp.oldval), oldlen,
-                          compat_ptr(tmp.newval), tmp.newlen);
-
-       if (result >= 0) {
-               oldlen = result;
-               result = 0;
-       }
-
-       if (compat_oldlenp && put_user(oldlen, compat_oldlenp))
-               return -EFAULT;
-
-       return result;
-}
-
-#endif /* CONFIG_COMPAT */
index 5c0848c..613b2d6 100644 (file)
@@ -42,7 +42,13 @@ task_work_add(struct task_struct *task, struct callback_head *work, int notify)
                set_notify_resume(task);
                break;
        case TWA_SIGNAL:
-               if (lock_task_sighand(task, &flags)) {
+               /*
+                * Only grab the sighand lock if we don't already have some
+                * task_work pending. This pairs with the smp_store_mb()
+                * in get_signal(), see comment there.
+                */
+               if (!(READ_ONCE(task->jobctl) & JOBCTL_TASK_WORK) &&
+                   lock_task_sighand(task, &flags)) {
                        task->jobctl |= JOBCTL_TASK_WORK;
                        signal_wake_up(task, 0);
                        unlock_task_sighand(task, &flags);
index fcc4235..a09b1d6 100644 (file)
@@ -52,6 +52,15 @@ config GENERIC_CLOCKEVENTS_MIN_ADJUST
 config GENERIC_CMOS_UPDATE
        bool
 
+# Select to handle posix CPU timers from task_work
+# and not from the timer interrupt context
+config HAVE_POSIX_CPU_TIMERS_TASK_WORK
+       bool
+
+config POSIX_CPU_TIMERS_TASK_WORK
+       bool
+       default y if POSIX_TIMERS && HAVE_POSIX_CPU_TIMERS_TASK_WORK
+
 if GENERIC_CLOCKEVENTS
 menu "Timers subsystem"
 
index 2ffb466..ca223a8 100644 (file)
@@ -192,7 +192,7 @@ static void alarmtimer_dequeue(struct alarm_base *base, struct alarm *alarm)
  * When a alarm timer fires, this runs through the timerqueue to
  * see which alarms expired, and runs those. If there are more alarm
  * timers queued for the future, we set the hrtimer to fire when
- * when the next future alarm timer expires.
+ * the next future alarm timer expires.
  */
 static enum hrtimer_restart alarmtimer_fired(struct hrtimer *timer)
 {
index 1651179..a71758e 100644 (file)
@@ -377,6 +377,7 @@ static int posix_cpu_clock_get(const clockid_t clock, struct timespec64 *tp)
  */
 static int posix_cpu_timer_create(struct k_itimer *new_timer)
 {
+       static struct lock_class_key posix_cpu_timers_key;
        struct pid *pid;
 
        rcu_read_lock();
@@ -386,6 +387,17 @@ static int posix_cpu_timer_create(struct k_itimer *new_timer)
                return -EINVAL;
        }
 
+       /*
+        * If posix timer expiry is handled in task work context then
+        * timer::it_lock can be taken without disabling interrupts as all
+        * other locking happens in task context. This requires a seperate
+        * lock class key otherwise regular posix timer expiry would record
+        * the lock class being taken in interrupt context and generate a
+        * false positive warning.
+        */
+       if (IS_ENABLED(CONFIG_POSIX_CPU_TIMERS_TASK_WORK))
+               lockdep_set_class(&new_timer->it_lock, &posix_cpu_timers_key);
+
        new_timer->kclock = &clock_posix_cpu;
        timerqueue_init(&new_timer->it.cpu.node);
        new_timer->it.cpu.pid = get_pid(pid);
@@ -1080,43 +1092,163 @@ static inline bool fastpath_timer_check(struct task_struct *tsk)
        return false;
 }
 
+static void handle_posix_cpu_timers(struct task_struct *tsk);
+
+#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
+static void posix_cpu_timers_work(struct callback_head *work)
+{
+       handle_posix_cpu_timers(current);
+}
+
 /*
- * This is called from the timer interrupt handler.  The irq handler has
- * already updated our counts.  We need to check if any timers fire now.
- * Interrupts are disabled.
+ * Initialize posix CPU timers task work in init task. Out of line to
+ * keep the callback static and to avoid header recursion hell.
  */
-void run_posix_cpu_timers(void)
+void __init posix_cputimers_init_work(void)
 {
-       struct task_struct *tsk = current;
-       struct k_itimer *timer, *next;
-       unsigned long flags;
-       LIST_HEAD(firing);
+       init_task_work(&current->posix_cputimers_work.work,
+                      posix_cpu_timers_work);
+}
 
-       lockdep_assert_irqs_disabled();
+/*
+ * Note: All operations on tsk->posix_cputimer_work.scheduled happen either
+ * in hard interrupt context or in task context with interrupts
+ * disabled. Aside of that the writer/reader interaction is always in the
+ * context of the current task, which means they are strict per CPU.
+ */
+static inline bool posix_cpu_timers_work_scheduled(struct task_struct *tsk)
+{
+       return tsk->posix_cputimers_work.scheduled;
+}
 
-       /*
-        * The fast path checks that there are no expired thread or thread
-        * group timers.  If that's so, just return.
-        */
-       if (!fastpath_timer_check(tsk))
+static inline void __run_posix_cpu_timers(struct task_struct *tsk)
+{
+       if (WARN_ON_ONCE(tsk->posix_cputimers_work.scheduled))
                return;
 
-       lockdep_posixtimer_enter();
-       if (!lock_task_sighand(tsk, &flags)) {
-               lockdep_posixtimer_exit();
-               return;
+       /* Schedule task work to actually expire the timers */
+       tsk->posix_cputimers_work.scheduled = true;
+       task_work_add(tsk, &tsk->posix_cputimers_work.work, TWA_RESUME);
+}
+
+static inline bool posix_cpu_timers_enable_work(struct task_struct *tsk,
+                                               unsigned long start)
+{
+       bool ret = true;
+
+       /*
+        * On !RT kernels interrupts are disabled while collecting expired
+        * timers, so no tick can happen and the fast path check can be
+        * reenabled without further checks.
+        */
+       if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {
+               tsk->posix_cputimers_work.scheduled = false;
+               return true;
        }
+
        /*
-        * Here we take off tsk->signal->cpu_timers[N] and
-        * tsk->cpu_timers[N] all the timers that are firing, and
-        * put them on the firing list.
+        * On RT enabled kernels ticks can happen while the expired timers
+        * are collected under sighand lock. But any tick which observes
+        * the CPUTIMERS_WORK_SCHEDULED bit set, does not run the fastpath
+        * checks. So reenabling the tick work has do be done carefully:
+        *
+        * Disable interrupts and run the fast path check if jiffies have
+        * advanced since the collecting of expired timers started. If
+        * jiffies have not advanced or the fast path check did not find
+        * newly expired timers, reenable the fast path check in the timer
+        * interrupt. If there are newly expired timers, return false and
+        * let the collection loop repeat.
         */
-       check_thread_timers(tsk, &firing);
+       local_irq_disable();
+       if (start != jiffies && fastpath_timer_check(tsk))
+               ret = false;
+       else
+               tsk->posix_cputimers_work.scheduled = false;
+       local_irq_enable();
+
+       return ret;
+}
+#else /* CONFIG_POSIX_CPU_TIMERS_TASK_WORK */
+static inline void __run_posix_cpu_timers(struct task_struct *tsk)
+{
+       lockdep_posixtimer_enter();
+       handle_posix_cpu_timers(tsk);
+       lockdep_posixtimer_exit();
+}
+
+static inline bool posix_cpu_timers_work_scheduled(struct task_struct *tsk)
+{
+       return false;
+}
+
+static inline bool posix_cpu_timers_enable_work(struct task_struct *tsk,
+                                               unsigned long start)
+{
+       return true;
+}
+#endif /* CONFIG_POSIX_CPU_TIMERS_TASK_WORK */
+
+static void handle_posix_cpu_timers(struct task_struct *tsk)
+{
+       struct k_itimer *timer, *next;
+       unsigned long flags, start;
+       LIST_HEAD(firing);
+
+       if (!lock_task_sighand(tsk, &flags))
+               return;
 
-       check_process_timers(tsk, &firing);
+       do {
+               /*
+                * On RT locking sighand lock does not disable interrupts,
+                * so this needs to be careful vs. ticks. Store the current
+                * jiffies value.
+                */
+               start = READ_ONCE(jiffies);
+               barrier();
+
+               /*
+                * Here we take off tsk->signal->cpu_timers[N] and
+                * tsk->cpu_timers[N] all the timers that are firing, and
+                * put them on the firing list.
+                */
+               check_thread_timers(tsk, &firing);
+
+               check_process_timers(tsk, &firing);
+
+               /*
+                * The above timer checks have updated the exipry cache and
+                * because nothing can have queued or modified timers after
+                * sighand lock was taken above it is guaranteed to be
+                * consistent. So the next timer interrupt fastpath check
+                * will find valid data.
+                *
+                * If timer expiry runs in the timer interrupt context then
+                * the loop is not relevant as timers will be directly
+                * expired in interrupt context. The stub function below
+                * returns always true which allows the compiler to
+                * optimize the loop out.
+                *
+                * If timer expiry is deferred to task work context then
+                * the following rules apply:
+                *
+                * - On !RT kernels no tick can have happened on this CPU
+                *   after sighand lock was acquired because interrupts are
+                *   disabled. So reenabling task work before dropping
+                *   sighand lock and reenabling interrupts is race free.
+                *
+                * - On RT kernels ticks might have happened but the tick
+                *   work ignored posix CPU timer handling because the
+                *   CPUTIMERS_WORK_SCHEDULED bit is set. Reenabling work
+                *   must be done very carefully including a check whether
+                *   ticks have happened since the start of the timer
+                *   expiry checks. posix_cpu_timers_enable_work() takes
+                *   care of that and eventually lets the expiry checks
+                *   run again.
+                */
+       } while (!posix_cpu_timers_enable_work(tsk, start));
 
        /*
-        * We must release these locks before taking any timer's lock.
+        * We must release sighand lock before taking any timer's lock.
         * There is a potential race with timer deletion here, as the
         * siglock now protects our private firing list.  We have set
         * the firing flag in each timer, so that a deletion attempt
@@ -1134,6 +1266,13 @@ void run_posix_cpu_timers(void)
        list_for_each_entry_safe(timer, next, &firing, it.cpu.elist) {
                int cpu_firing;
 
+               /*
+                * spin_lock() is sufficient here even independent of the
+                * expiry context. If expiry happens in hard interrupt
+                * context it's obvious. For task work context it's safe
+                * because all other operations on timer::it_lock happen in
+                * task context (syscall or exit).
+                */
                spin_lock(&timer->it_lock);
                list_del_init(&timer->it.cpu.elist);
                cpu_firing = timer->it.cpu.firing;
@@ -1147,7 +1286,34 @@ void run_posix_cpu_timers(void)
                        cpu_timer_fire(timer);
                spin_unlock(&timer->it_lock);
        }
-       lockdep_posixtimer_exit();
+}
+
+/*
+ * This is called from the timer interrupt handler.  The irq handler has
+ * already updated our counts.  We need to check if any timers fire now.
+ * Interrupts are disabled.
+ */
+void run_posix_cpu_timers(void)
+{
+       struct task_struct *tsk = current;
+
+       lockdep_assert_irqs_disabled();
+
+       /*
+        * If the actual expiry is deferred to task work context and the
+        * work is already scheduled there is no point to do anything here.
+        */
+       if (posix_cpu_timers_work_scheduled(tsk))
+               return;
+
+       /*
+        * The fast path checks that there are no expired thread or thread
+        * group timers.  If that's so, just return.
+        */
+       if (!fastpath_timer_check(tsk))
+               return;
+
+       __run_posix_cpu_timers(tsk);
 }
 
 /*
index 0deaf4b..1c03eec 100644 (file)
@@ -229,7 +229,7 @@ void __init generic_sched_clock_init(void)
 {
        /*
         * If no sched_clock() function has been provided at that point,
-        * make it the final one one.
+        * make it the final one.
         */
        if (cd.actual_read_sched_clock == jiffy_sched_clock_read)
                sched_clock_register(jiffy_sched_clock_read, BITS_PER_LONG, HZ);
index 406306b..4c47f38 100644 (file)
@@ -39,7 +39,7 @@ enum timekeeping_adv_mode {
        TK_ADV_FREQ
 };
 
-static DEFINE_RAW_SPINLOCK(timekeeper_lock);
+DEFINE_RAW_SPINLOCK(timekeeper_lock);
 
 /*
  * The most important data for readout fits into a single 64 byte
@@ -2004,7 +2004,7 @@ static inline unsigned int accumulate_nsecs_to_secs(struct timekeeper *tk)
  * logarithmic_accumulation - shifted accumulation of cycles
  *
  * This functions accumulates a shifted interval of cycles into
- * into a shifted interval nanoseconds. Allows for O(log) accumulation
+ * a shifted interval nanoseconds. Allows for O(log) accumulation
  * loop.
  *
  * Returns the unconsumed cycles.
index bcbb52d..4ca2787 100644 (file)
@@ -1,12 +1,14 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef _TIMEKEEPING_INTERNAL_H
 #define _TIMEKEEPING_INTERNAL_H
-/*
- * timekeeping debug functions
- */
+
 #include <linux/clocksource.h>
+#include <linux/spinlock.h>
 #include <linux/time.h>
 
+/*
+ * timekeeping debug functions
+ */
 #ifdef CONFIG_DEBUG_FS
 extern void tk_debug_account_sleep_time(const struct timespec64 *t);
 #else
@@ -31,4 +33,7 @@ static inline u64 clocksource_delta(u64 now, u64 last, u64 mask)
 }
 #endif
 
+/* Semi public for serialization of non timekeeper VDSO updates. */
+extern raw_spinlock_t timekeeper_lock;
+
 #endif /* _TIMEKEEPING_INTERNAL_H */
index ae5029f..a16764b 100644 (file)
@@ -2017,6 +2017,7 @@ static void __init init_timer_cpus(void)
 void __init init_timers(void)
 {
        init_timer_cpus();
+       posix_cputimers_init_work();
        open_softirq(TIMER_SOFTIRQ, run_timer_softirq);
 }
 
index 54ce6eb..88e6b8e 100644 (file)
@@ -13,6 +13,8 @@
 #include <vdso/helpers.h>
 #include <vdso/vsyscall.h>
 
+#include "timekeeping_internal.h"
+
 static inline void update_vdso_data(struct vdso_data *vdata,
                                    struct timekeeper *tk)
 {
@@ -127,3 +129,42 @@ void update_vsyscall_tz(void)
 
        __arch_sync_vdso_data(vdata);
 }
+
+/**
+ * vdso_update_begin - Start of a VDSO update section
+ *
+ * Allows architecture code to safely update the architecture specific VDSO
+ * data. Disables interrupts, acquires timekeeper lock to serialize against
+ * concurrent updates from timekeeping and invalidates the VDSO data
+ * sequence counter to prevent concurrent readers from accessing
+ * inconsistent data.
+ *
+ * Returns: Saved interrupt flags which need to be handed in to
+ * vdso_update_end().
+ */
+unsigned long vdso_update_begin(void)
+{
+       struct vdso_data *vdata = __arch_get_k_vdso_data();
+       unsigned long flags;
+
+       raw_spin_lock_irqsave(&timekeeper_lock, flags);
+       vdso_write_begin(vdata);
+       return flags;
+}
+
+/**
+ * vdso_update_end - End of a VDSO update section
+ * @flags:     Interrupt flags as returned from vdso_update_begin()
+ *
+ * Pairs with vdso_update_begin(). Marks vdso data consistent, invokes data
+ * synchronization if the architecture requires it, drops timekeeper lock
+ * and restores interrupt flags.
+ */
+void vdso_update_end(unsigned long flags)
+{
+       struct vdso_data *vdata = __arch_get_k_vdso_data();
+
+       vdso_write_end(vdata);
+       __arch_sync_vdso_data(vdata);
+       raw_spin_unlock_irqrestore(&timekeeper_lock, flags);
+}
index f74020f..0ef8f65 100644 (file)
@@ -393,6 +393,7 @@ static void free_watch(struct rcu_head *rcu)
        struct watch *watch = container_of(rcu, struct watch, rcu);
 
        put_watch_queue(rcu_access_pointer(watch->queue));
+       atomic_dec(&watch->cred->user->nr_watches);
        put_cred(watch->cred);
 }
 
@@ -452,6 +453,13 @@ int add_watch_to_object(struct watch *watch, struct watch_list *wlist)
        watch->cred = get_current_cred();
        rcu_assign_pointer(watch->watch_list, wlist);
 
+       if (atomic_inc_return(&watch->cred->user->nr_watches) >
+           task_rlimit(current, RLIMIT_NOFILE)) {
+               atomic_dec(&watch->cred->user->nr_watches);
+               put_cred(watch->cred);
+               return -EAGAIN;
+       }
+
        spin_lock_bh(&wqueue->lock);
        kref_get(&wqueue->usage);
        kref_get(&watch->usage);
index e290fc5..a4a4c68 100644 (file)
@@ -15,11 +15,16 @@ KCOV_INSTRUMENT_debugobjects.o := n
 KCOV_INSTRUMENT_dynamic_debug.o := n
 KCOV_INSTRUMENT_fault-inject.o := n
 
+# string.o implements standard library functions like memset/memcpy etc.
+# Use -ffreestanding to ensure that the compiler does not try to "optimize"
+# them into calls to themselves.
+CFLAGS_string.o := -ffreestanding
+
 # Early boot use of cmdline, don't instrument it
 ifdef CONFIG_AMD_MEM_ENCRYPT
 KASAN_SANITIZE_string.o := n
 
-CFLAGS_string.o := -fno-stack-protector
+CFLAGS_string.o += -fno-stack-protector
 endif
 
 # Used by KCSAN while enabled, avoid recursion.
index e909ab7..fbaa3e8 100644 (file)
@@ -70,27 +70,27 @@ static void bad_io_access(unsigned long port, const char *access)
 #define mmio_read64be(addr) swab64(readq(addr))
 #endif
 
-unsigned int ioread8(void __iomem *addr)
+unsigned int ioread8(const void __iomem *addr)
 {
        IO_COND(addr, return inb(port), return readb(addr));
        return 0xff;
 }
-unsigned int ioread16(void __iomem *addr)
+unsigned int ioread16(const void __iomem *addr)
 {
        IO_COND(addr, return inw(port), return readw(addr));
        return 0xffff;
 }
-unsigned int ioread16be(void __iomem *addr)
+unsigned int ioread16be(const void __iomem *addr)
 {
        IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
        return 0xffff;
 }
-unsigned int ioread32(void __iomem *addr)
+unsigned int ioread32(const void __iomem *addr)
 {
        IO_COND(addr, return inl(port), return readl(addr));
        return 0xffffffff;
 }
-unsigned int ioread32be(void __iomem *addr)
+unsigned int ioread32be(const void __iomem *addr)
 {
        IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
        return 0xffffffff;
@@ -142,26 +142,26 @@ static u64 pio_read64be_hi_lo(unsigned long port)
        return lo | (hi << 32);
 }
 
-u64 ioread64_lo_hi(void __iomem *addr)
+u64 ioread64_lo_hi(const void __iomem *addr)
 {
        IO_COND(addr, return pio_read64_lo_hi(port), return readq(addr));
        return 0xffffffffffffffffULL;
 }
 
-u64 ioread64_hi_lo(void __iomem *addr)
+u64 ioread64_hi_lo(const void __iomem *addr)
 {
        IO_COND(addr, return pio_read64_hi_lo(port), return readq(addr));
        return 0xffffffffffffffffULL;
 }
 
-u64 ioread64be_lo_hi(void __iomem *addr)
+u64 ioread64be_lo_hi(const void __iomem *addr)
 {
        IO_COND(addr, return pio_read64be_lo_hi(port),
                return mmio_read64be(addr));
        return 0xffffffffffffffffULL;
 }
 
-u64 ioread64be_hi_lo(void __iomem *addr)
+u64 ioread64be_hi_lo(const void __iomem *addr)
 {
        IO_COND(addr, return pio_read64be_hi_lo(port),
                return mmio_read64be(addr));
@@ -275,7 +275,7 @@ EXPORT_SYMBOL(iowrite64be_hi_lo);
  * order" (we also don't have IO barriers).
  */
 #ifndef mmio_insb
-static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
+static inline void mmio_insb(const void __iomem *addr, u8 *dst, int count)
 {
        while (--count >= 0) {
                u8 data = __raw_readb(addr);
@@ -283,7 +283,7 @@ static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
                dst++;
        }
 }
-static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
+static inline void mmio_insw(const void __iomem *addr, u16 *dst, int count)
 {
        while (--count >= 0) {
                u16 data = __raw_readw(addr);
@@ -291,7 +291,7 @@ static inline void mmio_insw(void __iomem *addr, u16 *dst, int count)
                dst++;
        }
 }
-static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
+static inline void mmio_insl(const void __iomem *addr, u32 *dst, int count)
 {
        while (--count >= 0) {
                u32 data = __raw_readl(addr);
@@ -325,15 +325,15 @@ static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
 }
 #endif
 
-void ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        IO_COND(addr, insb(port,dst,count), mmio_insb(addr, dst, count));
 }
-void ioread16_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        IO_COND(addr, insw(port,dst,count), mmio_insw(addr, dst, count));
 }
-void ioread32_rep(void __iomem *addr, void *dst, unsigned long count)
+void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count)
 {
        IO_COND(addr, insl(port,dst,count), mmio_insl(addr, dst, count));
 }
index cc7b6d4..90bb679 100644 (file)
@@ -446,7 +446,7 @@ _last_literals:
                        *op++ = (BYTE)(lastRun << ML_BITS);
                }
 
-               memcpy(op, anchor, lastRun);
+               LZ4_memcpy(op, anchor, lastRun);
 
                op += lastRun;
        }
@@ -708,7 +708,7 @@ _last_literals:
                } else {
                        *op++ = (BYTE)(lastRunSize<<ML_BITS);
                }
-               memcpy(op, anchor, lastRunSize);
+               LZ4_memcpy(op, anchor, lastRunSize);
                op += lastRunSize;
        }
 
index 5371dab..00cb0d0 100644 (file)
@@ -153,7 +153,7 @@ static FORCE_INLINE int LZ4_decompress_generic(
                   && likely((endOnInput ? ip < shortiend : 1) &
                             (op <= shortoend))) {
                        /* Copy the literals */
-                       memcpy(op, ip, endOnInput ? 16 : 8);
+                       LZ4_memcpy(op, ip, endOnInput ? 16 : 8);
                        op += length; ip += length;
 
                        /*
@@ -172,9 +172,9 @@ static FORCE_INLINE int LZ4_decompress_generic(
                            (offset >= 8) &&
                            (dict == withPrefix64k || match >= lowPrefix)) {
                                /* Copy the match. */
-                               memcpy(op + 0, match + 0, 8);
-                               memcpy(op + 8, match + 8, 8);
-                               memcpy(op + 16, match + 16, 2);
+                               LZ4_memcpy(op + 0, match + 0, 8);
+                               LZ4_memcpy(op + 8, match + 8, 8);
+                               LZ4_memcpy(op + 16, match + 16, 2);
                                op += length + MINMATCH;
                                /* Both stages worked, load the next token. */
                                continue;
@@ -263,7 +263,7 @@ static FORCE_INLINE int LZ4_decompress_generic(
                                }
                        }
 
-                       memcpy(op, ip, length);
+                       LZ4_memcpy(op, ip, length);
                        ip += length;
                        op += length;
 
@@ -350,7 +350,7 @@ _copy_match:
                                size_t const copySize = (size_t)(lowPrefix - match);
                                size_t const restSize = length - copySize;
 
-                               memcpy(op, dictEnd - copySize, copySize);
+                               LZ4_memcpy(op, dictEnd - copySize, copySize);
                                op += copySize;
                                if (restSize > (size_t)(op - lowPrefix)) {
                                        /* overlap copy */
@@ -360,7 +360,7 @@ _copy_match:
                                        while (op < endOfMatch)
                                                *op++ = *copyFrom++;
                                } else {
-                                       memcpy(op, lowPrefix, restSize);
+                                       LZ4_memcpy(op, lowPrefix, restSize);
                                        op += restSize;
                                }
                        }
@@ -386,7 +386,7 @@ _copy_match:
                                while (op < copyEnd)
                                        *op++ = *match++;
                        } else {
-                               memcpy(op, match, mlen);
+                               LZ4_memcpy(op, match, mlen);
                        }
                        op = copyEnd;
                        if (op == oend)
@@ -400,7 +400,7 @@ _copy_match:
                        op[2] = match[2];
                        op[3] = match[3];
                        match += inc32table[offset];
-                       memcpy(op + 4, match, 4);
+                       LZ4_memcpy(op + 4, match, 4);
                        match -= dec64table[offset];
                } else {
                        LZ4_copy8(op, match);
index 1a7fa9d..c91dd96 100644 (file)
@@ -137,6 +137,16 @@ static FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value)
        return put_unaligned_le16(value, memPtr);
 }
 
+/*
+ * LZ4 relies on memcpy with a constant size being inlined. In freestanding
+ * environments, the compiler can't assume the implementation of memcpy() is
+ * standard compliant, so apply its specialized memcpy() inlining logic. When
+ * possible, use __builtin_memcpy() to tell the compiler to analyze memcpy()
+ * as-if it were standard compliant, so it can inline it in freestanding
+ * environments. This is needed when decompressing the Linux Kernel, for example.
+ */
+#define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
+
 static FORCE_INLINE void LZ4_copy8(void *dst, const void *src)
 {
 #if LZ4_ARCH64
index 1b61d87..e7ac869 100644 (file)
@@ -570,7 +570,7 @@ _Search3:
                        *op++ = (BYTE) lastRun;
                } else
                        *op++ = (BYTE)(lastRun<<ML_BITS);
-               memcpy(op, anchor, iend - anchor);
+               LZ4_memcpy(op, anchor, iend - anchor);
                op += iend - anchor;
        }
 
index bcc9a98..2919f16 100644 (file)
@@ -68,7 +68,7 @@ static int do_hres_timens(const struct vdso_data *vdns, clockid_t clk,
                if (unlikely(!vdso_clocksource_ok(vd)))
                        return -1;
 
-               cycles = __arch_get_hw_counter(vd->clock_mode);
+               cycles = __arch_get_hw_counter(vd->clock_mode, vd);
                if (unlikely(!vdso_cycles_ok(cycles)))
                        return -1;
                ns = vdso_ts->nsec;
@@ -138,7 +138,7 @@ static __always_inline int do_hres(const struct vdso_data *vd, clockid_t clk,
                if (unlikely(!vdso_clocksource_ok(vd)))
                        return -1;
 
-               cycles = __arch_get_hw_counter(vd->clock_mode);
+               cycles = __arch_get_hw_counter(vd->clock_mode, vd);
                if (unlikely(!vdso_cycles_ok(cycles)))
                        return -1;
                ns = vdso_ts->nsec;
index b89581b..176dcde 100644 (file)
@@ -1009,7 +1009,7 @@ isolate_migratepages_block(struct compact_control *cc, unsigned long low_pfn,
                del_page_from_lru_list(page, lruvec, page_lru(page));
                mod_node_page_state(page_pgdat(page),
                                NR_ISOLATED_ANON + page_is_file_lru(page),
-                               hpage_nr_pages(page));
+                               thp_nr_pages(page));
 
 isolate_success:
                list_add(&page->lru, &cc->migratepages);
index 8e75bce..1aaea26 100644 (file)
@@ -198,7 +198,7 @@ static void unaccount_page_cache_page(struct address_space *mapping,
        if (PageHuge(page))
                return;
 
-       nr = hpage_nr_pages(page);
+       nr = thp_nr_pages(page);
 
        __mod_lruvec_page_state(page, NR_FILE_PAGES, -nr);
        if (PageSwapBacked(page)) {
@@ -2468,6 +2468,7 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
        struct address_space *mapping = file->f_mapping;
        struct file *fpin = NULL;
        pgoff_t offset = vmf->pgoff;
+       unsigned int mmap_miss;
 
        /* If we don't want any read-ahead, don't bother */
        if (vmf->vma->vm_flags & VM_RAND_READ)
@@ -2483,14 +2484,15 @@ static struct file *do_sync_mmap_readahead(struct vm_fault *vmf)
        }
 
        /* Avoid banging the cache line if not needed */
-       if (ra->mmap_miss < MMAP_LOTSAMISS * 10)
-               ra->mmap_miss++;
+       mmap_miss = READ_ONCE(ra->mmap_miss);
+       if (mmap_miss < MMAP_LOTSAMISS * 10)
+               WRITE_ONCE(ra->mmap_miss, ++mmap_miss);
 
        /*
         * Do we miss much more than hit in this file? If so,
         * stop bothering with read-ahead. It will only hurt.
         */
-       if (ra->mmap_miss > MMAP_LOTSAMISS)
+       if (mmap_miss > MMAP_LOTSAMISS)
                return fpin;
 
        /*
@@ -2516,13 +2518,15 @@ static struct file *do_async_mmap_readahead(struct vm_fault *vmf,
        struct file_ra_state *ra = &file->f_ra;
        struct address_space *mapping = file->f_mapping;
        struct file *fpin = NULL;
+       unsigned int mmap_miss;
        pgoff_t offset = vmf->pgoff;
 
        /* If we don't want any read-ahead, don't bother */
        if (vmf->vma->vm_flags & VM_RAND_READ || !ra->ra_pages)
                return fpin;
-       if (ra->mmap_miss > 0)
-               ra->mmap_miss--;
+       mmap_miss = READ_ONCE(ra->mmap_miss);
+       if (mmap_miss)
+               WRITE_ONCE(ra->mmap_miss, --mmap_miss);
        if (PageReadahead(page)) {
                fpin = maybe_unlock_mmap_for_io(vmf, fpin);
                page_cache_async_readahead(mapping, ra, file,
@@ -2688,6 +2692,7 @@ void filemap_map_pages(struct vm_fault *vmf,
        unsigned long max_idx;
        XA_STATE(xas, &mapping->i_pages, start_pgoff);
        struct page *page;
+       unsigned int mmap_miss = READ_ONCE(file->f_ra.mmap_miss);
 
        rcu_read_lock();
        xas_for_each(&xas, page, end_pgoff) {
@@ -2724,8 +2729,8 @@ void filemap_map_pages(struct vm_fault *vmf,
                if (page->index >= max_idx)
                        goto unlock;
 
-               if (file->f_ra.mmap_miss > 0)
-                       file->f_ra.mmap_miss--;
+               if (mmap_miss > 0)
+                       mmap_miss--;
 
                vmf->address += (xas.xa_index - last_pgoff) << PAGE_SHIFT;
                if (vmf->pte)
@@ -2745,6 +2750,7 @@ next:
                        break;
        }
        rcu_read_unlock();
+       WRITE_ONCE(file->f_ra.mmap_miss, mmap_miss);
 }
 EXPORT_SYMBOL(filemap_map_pages);
 
index 9d977b1..2183a56 100644 (file)
@@ -61,16 +61,16 @@ static u64 frontswap_failed_stores;
 static u64 frontswap_invalidates;
 
 static inline void inc_frontswap_loads(void) {
-       frontswap_loads++;
+       data_race(frontswap_loads++);
 }
 static inline void inc_frontswap_succ_stores(void) {
-       frontswap_succ_stores++;
+       data_race(frontswap_succ_stores++);
 }
 static inline void inc_frontswap_failed_stores(void) {
-       frontswap_failed_stores++;
+       data_race(frontswap_failed_stores++);
 }
 static inline void inc_frontswap_invalidates(void) {
-       frontswap_invalidates++;
+       data_race(frontswap_invalidates++);
 }
 #else
 static inline void inc_frontswap_loads(void) { }
index 39e58df..ae096ea 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1637,7 +1637,7 @@ check_again:
                                        mod_node_page_state(page_pgdat(head),
                                                            NR_ISOLATED_ANON +
                                                            page_is_file_lru(head),
-                                                           hpage_nr_pages(head));
+                                                           thp_nr_pages(head));
                                }
                        }
                }
index d11a9a8..10c6776 100644 (file)
@@ -369,7 +369,7 @@ extern void clear_page_mlock(struct page *page);
 static inline void mlock_migrate_page(struct page *newpage, struct page *page)
 {
        if (TestClearPageMlocked(page)) {
-               int nr_pages = hpage_nr_pages(page);
+               int nr_pages = thp_nr_pages(page);
 
                /* Holding pmd lock, no change in irq context: __mod is safe */
                __mod_zone_page_state(page_zone(page), NR_MLOCK, -nr_pages);
@@ -396,7 +396,7 @@ vma_address(struct page *page, struct vm_area_struct *vma)
        unsigned long start, end;
 
        start = __vma_address(page, vma);
-       end = start + PAGE_SIZE * (hpage_nr_pages(page) - 1);
+       end = start + thp_size(page) - PAGE_SIZE;
 
        /* page should be within @vma mapping range */
        VM_BUG_ON_VMA(end < vma->vm_start || start >= vma->vm_end, vma);
index e362dc3..5e252d9 100644 (file)
@@ -1169,8 +1169,10 @@ static bool update_checksum(struct kmemleak_object *object)
        u32 old_csum = object->checksum;
 
        kasan_disable_current();
+       kcsan_disable_current();
        object->checksum = crc32(0, (void *)object->pointer, object->size);
        kasan_enable_current();
+       kcsan_enable_current();
 
        return object->checksum != old_csum;
 }
index e825804..5aa6e44 100644 (file)
@@ -180,7 +180,7 @@ unsigned long list_lru_count_one(struct list_lru *lru,
 
        rcu_read_lock();
        l = list_lru_from_memcg_idx(nlru, memcg_cache_id(memcg));
-       count = l->nr_items;
+       count = READ_ONCE(l->nr_items);
        rcu_read_unlock();
 
        return count;
index 9d87082..b807952 100644 (file)
@@ -5589,7 +5589,7 @@ static int mem_cgroup_move_account(struct page *page,
 {
        struct lruvec *from_vec, *to_vec;
        struct pglist_data *pgdat;
-       unsigned int nr_pages = compound ? hpage_nr_pages(page) : 1;
+       unsigned int nr_pages = compound ? thp_nr_pages(page) : 1;
        int ret;
 
        VM_BUG_ON(from == to);
@@ -6682,7 +6682,7 @@ void mem_cgroup_calculate_protection(struct mem_cgroup *root,
  */
 int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask)
 {
-       unsigned int nr_pages = hpage_nr_pages(page);
+       unsigned int nr_pages = thp_nr_pages(page);
        struct mem_cgroup *memcg = NULL;
        int ret = 0;
 
@@ -6912,7 +6912,7 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage)
                return;
 
        /* Force-charge the new page. The old one will be freed soon */
-       nr_pages = hpage_nr_pages(newpage);
+       nr_pages = thp_nr_pages(newpage);
 
        page_counter_charge(&memcg->memory, nr_pages);
        if (do_memsw_account())
@@ -7114,7 +7114,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
         * ancestor for the swap instead and transfer the memory+swap charge.
         */
        swap_memcg = mem_cgroup_id_get_online(memcg);
-       nr_entries = hpage_nr_pages(page);
+       nr_entries = thp_nr_pages(page);
        /* Get references for the tail pages, too */
        if (nr_entries > 1)
                mem_cgroup_id_get_many(swap_memcg, nr_entries - 1);
@@ -7158,7 +7158,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
  */
 int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry)
 {
-       unsigned int nr_pages = hpage_nr_pages(page);
+       unsigned int nr_pages = thp_nr_pages(page);
        struct page_counter *counter;
        struct mem_cgroup *memcg;
        unsigned short oldid;
index 228efac..602f428 100644 (file)
@@ -2411,8 +2411,6 @@ static inline bool cow_user_page(struct page *dst, struct page *src,
        struct mm_struct *mm = vma->vm_mm;
        unsigned long addr = vmf->address;
 
-       debug_dma_assert_idle(src);
-
        if (likely(src)) {
                copy_user_highpage(dst, src, addr, vma);
                return true;
@@ -3130,8 +3128,8 @@ vm_fault_t do_swap_page(struct vm_fault *vmf)
        if (!page) {
                struct swap_info_struct *si = swp_swap_info(entry);
 
-               if (si->flags & SWP_SYNCHRONOUS_IO &&
-                               __swap_count(entry) == 1) {
+               if (data_race(si->flags & SWP_SYNCHRONOUS_IO) &&
+                   __swap_count(entry) == 1) {
                        /* skip swapcache */
                        page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma,
                                                        vmf->address);
@@ -4249,6 +4247,9 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf)
                                vmf->flags & FAULT_FLAG_WRITE)) {
                update_mmu_cache(vmf->vma, vmf->address, vmf->pte);
        } else {
+               /* Skip spurious TLB flush for retried page fault */
+               if (vmf->flags & FAULT_FLAG_TRIED)
+                       goto unlock;
                /*
                 * This is needed only for protection faults but the arch code
                 * is not yet telling us if this is a protection fault or not.
index c32ead8..e9d5ab5 100644 (file)
@@ -1299,7 +1299,7 @@ static int
 do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
 {
        unsigned long pfn;
-       struct page *page;
+       struct page *page, *head;
        int ret = 0;
        LIST_HEAD(source);
 
@@ -1307,15 +1307,14 @@ do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
                if (!pfn_valid(pfn))
                        continue;
                page = pfn_to_page(pfn);
+               head = compound_head(page);
 
                if (PageHuge(page)) {
-                       struct page *head = compound_head(page);
                        pfn = page_to_pfn(head) + compound_nr(head) - 1;
                        isolate_huge_page(head, &source);
                        continue;
                } else if (PageTransHuge(page))
-                       pfn = page_to_pfn(compound_head(page))
-                               + hpage_nr_pages(page) - 1;
+                       pfn = page_to_pfn(head) + thp_nr_pages(page) - 1;
 
                /*
                 * HWPoison pages have elevated reference counts so the migration would
index afaa09f..eddbe4e 100644 (file)
@@ -1049,7 +1049,7 @@ static int migrate_page_add(struct page *page, struct list_head *pagelist,
                        list_add_tail(&head->lru, pagelist);
                        mod_node_page_state(page_pgdat(head),
                                NR_ISOLATED_ANON + page_is_file_lru(head),
-                               hpage_nr_pages(head));
+                               thp_nr_pages(head));
                } else if (flags & MPOL_MF_STRICT) {
                        /*
                         * Non-movable page may reach here.  And, there may be
index 85efab3..79bff63 100644 (file)
@@ -489,7 +489,7 @@ void mempool_free(void *element, mempool_t *pool)
         * ensures that there will be frees which return elements to the
         * pool waking up the waiters.
         */
-       if (unlikely(pool->curr_nr < pool->min_nr)) {
+       if (unlikely(READ_ONCE(pool->curr_nr) < pool->min_nr)) {
                spin_lock_irqsave(&pool->lock, flags);
                if (likely(pool->curr_nr < pool->min_nr)) {
                        add_element(pool, element);
index 5053439..34a842a 100644 (file)
@@ -193,7 +193,7 @@ void putback_movable_pages(struct list_head *l)
                        put_page(page);
                } else {
                        mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON +
-                                       page_is_file_lru(page), -hpage_nr_pages(page));
+                                       page_is_file_lru(page), -thp_nr_pages(page));
                        putback_lru_page(page);
                }
        }
@@ -386,7 +386,7 @@ static int expected_page_refs(struct address_space *mapping, struct page *page)
         */
        expected_count += is_device_private_page(page);
        if (mapping)
-               expected_count += hpage_nr_pages(page) + page_has_private(page);
+               expected_count += thp_nr_pages(page) + page_has_private(page);
 
        return expected_count;
 }
@@ -441,7 +441,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
         */
        newpage->index = page->index;
        newpage->mapping = page->mapping;
-       page_ref_add(newpage, hpage_nr_pages(page)); /* add cache reference */
+       page_ref_add(newpage, thp_nr_pages(page)); /* add cache reference */
        if (PageSwapBacked(page)) {
                __SetPageSwapBacked(newpage);
                if (PageSwapCache(page)) {
@@ -474,7 +474,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
         * to one less reference.
         * We know this isn't the last reference.
         */
-       page_ref_unfreeze(page, expected_count - hpage_nr_pages(page));
+       page_ref_unfreeze(page, expected_count - thp_nr_pages(page));
 
        xas_unlock(&xas);
        /* Leave irq disabled to prevent preemption while updating stats */
@@ -591,7 +591,7 @@ static void copy_huge_page(struct page *dst, struct page *src)
        } else {
                /* thp page */
                BUG_ON(!PageTransHuge(src));
-               nr_pages = hpage_nr_pages(src);
+               nr_pages = thp_nr_pages(src);
        }
 
        for (i = 0; i < nr_pages; i++) {
@@ -1213,7 +1213,7 @@ out:
                 */
                if (likely(!__PageMovable(page)))
                        mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON +
-                                       page_is_file_lru(page), -hpage_nr_pages(page));
+                                       page_is_file_lru(page), -thp_nr_pages(page));
        }
 
        /*
@@ -1446,7 +1446,7 @@ retry:
                         * during migration.
                         */
                        is_thp = PageTransHuge(page);
-                       nr_subpages = hpage_nr_pages(page);
+                       nr_subpages = thp_nr_pages(page);
                        cond_resched();
 
                        if (PageHuge(page))
@@ -1670,7 +1670,7 @@ static int add_page_for_migration(struct mm_struct *mm, unsigned long addr,
                list_add_tail(&head->lru, pagelist);
                mod_node_page_state(page_pgdat(head),
                        NR_ISOLATED_ANON + page_is_file_lru(head),
-                       hpage_nr_pages(head));
+                       thp_nr_pages(head));
        }
 out_putpage:
        /*
@@ -2034,7 +2034,7 @@ static int numamigrate_isolate_page(pg_data_t *pgdat, struct page *page)
 
        page_lru = page_is_file_lru(page);
        mod_node_page_state(page_pgdat(page), NR_ISOLATED_ANON + page_lru,
-                               hpage_nr_pages(page));
+                               thp_nr_pages(page));
 
        /*
         * Isolating the page has taken another reference, so the
index f873613..93ca2bf 100644 (file)
@@ -61,8 +61,7 @@ void clear_page_mlock(struct page *page)
        if (!TestClearPageMlocked(page))
                return;
 
-       mod_zone_page_state(page_zone(page), NR_MLOCK,
-                           -hpage_nr_pages(page));
+       mod_zone_page_state(page_zone(page), NR_MLOCK, -thp_nr_pages(page));
        count_vm_event(UNEVICTABLE_PGCLEARED);
        /*
         * The previous TestClearPageMlocked() corresponds to the smp_mb()
@@ -95,7 +94,7 @@ void mlock_vma_page(struct page *page)
 
        if (!TestSetPageMlocked(page)) {
                mod_zone_page_state(page_zone(page), NR_MLOCK,
-                                   hpage_nr_pages(page));
+                                   thp_nr_pages(page));
                count_vm_event(UNEVICTABLE_PGMLOCKED);
                if (!isolate_lru_page(page))
                        putback_lru_page(page);
@@ -192,7 +191,7 @@ unsigned int munlock_vma_page(struct page *page)
        /*
         * Serialize with any parallel __split_huge_page_refcount() which
         * might otherwise copy PageMlocked to part of the tail pages before
-        * we clear it in the head page. It also stabilizes hpage_nr_pages().
+        * we clear it in the head page. It also stabilizes thp_nr_pages().
         */
        spin_lock_irq(&pgdat->lru_lock);
 
@@ -202,7 +201,7 @@ unsigned int munlock_vma_page(struct page *page)
                goto unlock_out;
        }
 
-       nr_pages = hpage_nr_pages(page);
+       nr_pages = thp_nr_pages(page);
        __mod_zone_page_state(page_zone(page), NR_MLOCK, -nr_pages);
 
        if (__munlock_isolate_lru_page(page, true)) {
index 8b7d0ec..0e2bab4 100644 (file)
@@ -666,8 +666,6 @@ void prep_compound_page(struct page *page, unsigned int order)
        int i;
        int nr_pages = 1 << order;
 
-       set_compound_page_dtor(page, COMPOUND_PAGE_DTOR);
-       set_compound_order(page, order);
        __SetPageHead(page);
        for (i = 1; i < nr_pages; i++) {
                struct page *p = page + i;
@@ -675,6 +673,9 @@ void prep_compound_page(struct page *page, unsigned int order)
                p->mapping = TAIL_MAPPING;
                set_compound_head(p, page);
        }
+
+       set_compound_page_dtor(page, COMPOUND_PAGE_DTOR);
+       set_compound_order(page, order);
        atomic_set(compound_mapcount_ptr(page), -1);
        if (hpage_pincount_available(page))
                atomic_set(compound_pincount_ptr(page), 0);
index b466384..afe22ad 100644 (file)
@@ -77,8 +77,8 @@ void page_counter_charge(struct page_counter *counter, unsigned long nr_pages)
                 * This is indeed racy, but we can live with some
                 * inaccuracy in the watermark.
                 */
-               if (new > c->watermark)
-                       c->watermark = new;
+               if (new > READ_ONCE(c->watermark))
+                       WRITE_ONCE(c->watermark, new);
        }
 }
 
@@ -119,9 +119,10 @@ bool page_counter_try_charge(struct page_counter *counter,
                        propagate_protected_usage(c, new);
                        /*
                         * This is racy, but we can live with some
-                        * inaccuracy in the failcnt.
+                        * inaccuracy in the failcnt which is only used
+                        * to report stats.
                         */
-                       c->failcnt++;
+                       data_race(c->failcnt++);
                        *fail = c;
                        goto failed;
                }
@@ -130,8 +131,8 @@ bool page_counter_try_charge(struct page_counter *counter,
                 * Just like with failcnt, we can live with some
                 * inaccuracy in the watermark.
                 */
-               if (new > c->watermark)
-                       c->watermark = new;
+               if (new > READ_ONCE(c->watermark))
+                       WRITE_ONCE(c->watermark, new);
        }
        return true;
 
index 9e36256..e485a6e 100644 (file)
@@ -40,7 +40,7 @@ static struct bio *get_swap_bio(gfp_t gfp_flags,
                bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9;
                bio->bi_end_io = end_io;
 
-               bio_add_page(bio, page, PAGE_SIZE * hpage_nr_pages(page), 0);
+               bio_add_page(bio, page, thp_size(page), 0);
        }
        return bio;
 }
@@ -85,7 +85,7 @@ static void swap_slot_free_notify(struct page *page)
                return;
 
        sis = page_swap_info(page);
-       if (!(sis->flags & SWP_BLKDEV))
+       if (data_race(!(sis->flags & SWP_BLKDEV)))
                return;
 
        /*
@@ -274,7 +274,7 @@ static inline void count_swpout_vm_event(struct page *page)
        if (unlikely(PageTransHuge(page)))
                count_vm_event(THP_SWPOUT);
 #endif
-       count_vm_events(PSWPOUT, hpage_nr_pages(page));
+       count_vm_events(PSWPOUT, thp_nr_pages(page));
 }
 
 #if defined(CONFIG_MEMCG) && defined(CONFIG_BLK_CGROUP)
@@ -302,7 +302,7 @@ int __swap_writepage(struct page *page, struct writeback_control *wbc,
        struct swap_info_struct *sis = page_swap_info(page);
 
        VM_BUG_ON_PAGE(!PageSwapCache(page), page);
-       if (sis->flags & SWP_FS) {
+       if (data_race(sis->flags & SWP_FS)) {
                struct kiocb kiocb;
                struct file *swap_file = sis->swap_file;
                struct address_space *mapping = swap_file->f_mapping;
@@ -393,7 +393,7 @@ int swap_readpage(struct page *page, bool synchronous)
                goto out;
        }
 
-       if (sis->flags & SWP_FS) {
+       if (data_race(sis->flags & SWP_FS)) {
                struct file *swap_file = sis->swap_file;
                struct address_space *mapping = swap_file->f_mapping;
 
@@ -455,7 +455,7 @@ int swap_set_page_dirty(struct page *page)
 {
        struct swap_info_struct *sis = page_swap_info(page);
 
-       if (sis->flags & SWP_FS) {
+       if (data_race(sis->flags & SWP_FS)) {
                struct address_space *mapping = sis->swap_file->f_mapping;
 
                VM_BUG_ON_PAGE(!PageSwapCache(page), page);
index 719c352..5e77b26 100644 (file)
@@ -61,7 +61,7 @@ static inline bool pfn_is_match(struct page *page, unsigned long pfn)
                return page_pfn == pfn;
 
        /* THP can be referenced by any subpage */
-       return pfn >= page_pfn && pfn - page_pfn < hpage_nr_pages(page);
+       return pfn >= page_pfn && pfn - page_pfn < thp_nr_pages(page);
 }
 
 /**
@@ -227,7 +227,7 @@ next_pte:
                        if (pvmw->address >= pvmw->vma->vm_end ||
                            pvmw->address >=
                                        __vma_address(pvmw->page, pvmw->vma) +
-                                       hpage_nr_pages(pvmw->page) * PAGE_SIZE)
+                                       thp_size(pvmw->page))
                                return not_found(pvmw);
                        /* Did we cross page table boundary? */
                        if (pvmw->address % PMD_SIZE == 0) {
@@ -268,7 +268,7 @@ int page_mapped_in_vma(struct page *page, struct vm_area_struct *vma)
        unsigned long start, end;
 
        start = __vma_address(page, vma);
-       end = start + PAGE_SIZE * (hpage_nr_pages(page) - 1);
+       end = start + thp_size(page) - PAGE_SIZE;
 
        if (unlikely(end < vma->vm_start || start >= vma->vm_end))
                return 0;
index 6cce9ef..83cc459 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -672,7 +672,7 @@ static bool should_defer_flush(struct mm_struct *mm, enum ttu_flags flags)
  */
 void flush_tlb_batched_pending(struct mm_struct *mm)
 {
-       if (mm->tlb_flush_batched) {
+       if (data_race(mm->tlb_flush_batched)) {
                flush_tlb_mm(mm);
 
                /*
@@ -1130,7 +1130,7 @@ void do_page_add_anon_rmap(struct page *page,
        }
 
        if (first) {
-               int nr = compound ? hpage_nr_pages(page) : 1;
+               int nr = compound ? thp_nr_pages(page) : 1;
                /*
                 * We use the irq-unsafe __{inc|mod}_zone_page_stat because
                 * these counters are not modified in interrupt context, and
@@ -1169,7 +1169,7 @@ void do_page_add_anon_rmap(struct page *page,
 void page_add_new_anon_rmap(struct page *page,
        struct vm_area_struct *vma, unsigned long address, bool compound)
 {
-       int nr = compound ? hpage_nr_pages(page) : 1;
+       int nr = compound ? thp_nr_pages(page) : 1;
 
        VM_BUG_ON_VMA(address < vma->vm_start || address >= vma->vm_end, vma);
        __SetPageSwapBacked(page);
@@ -1860,7 +1860,7 @@ static void rmap_walk_anon(struct page *page, struct rmap_walk_control *rwc,
                return;
 
        pgoff_start = page_to_pgoff(page);
-       pgoff_end = pgoff_start + hpage_nr_pages(page) - 1;
+       pgoff_end = pgoff_start + thp_nr_pages(page) - 1;
        anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root,
                        pgoff_start, pgoff_end) {
                struct vm_area_struct *vma = avc->vma;
@@ -1913,7 +1913,7 @@ static void rmap_walk_file(struct page *page, struct rmap_walk_control *rwc,
                return;
 
        pgoff_start = page_to_pgoff(page);
-       pgoff_end = pgoff_start + hpage_nr_pages(page) - 1;
+       pgoff_end = pgoff_start + thp_nr_pages(page) - 1;
        if (!locked)
                i_mmap_lock_read(mapping);
        vma_interval_tree_foreach(vma, &mapping->i_mmap,
index 9285e60..d16d65d 100644 (file)
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -241,7 +241,7 @@ static void pagevec_move_tail_fn(struct page *page, struct lruvec *lruvec,
                del_page_from_lru_list(page, lruvec, page_lru(page));
                ClearPageActive(page);
                add_page_to_lru_list_tail(page, lruvec, page_lru(page));
-               (*pgmoved) += hpage_nr_pages(page);
+               (*pgmoved) += thp_nr_pages(page);
        }
 }
 
@@ -312,7 +312,7 @@ void lru_note_cost(struct lruvec *lruvec, bool file, unsigned int nr_pages)
 void lru_note_cost_page(struct page *page)
 {
        lru_note_cost(mem_cgroup_page_lruvec(page, page_pgdat(page)),
-                     page_is_file_lru(page), hpage_nr_pages(page));
+                     page_is_file_lru(page), thp_nr_pages(page));
 }
 
 static void __activate_page(struct page *page, struct lruvec *lruvec,
@@ -320,7 +320,7 @@ static void __activate_page(struct page *page, struct lruvec *lruvec,
 {
        if (PageLRU(page) && !PageActive(page) && !PageUnevictable(page)) {
                int lru = page_lru_base_type(page);
-               int nr_pages = hpage_nr_pages(page);
+               int nr_pages = thp_nr_pages(page);
 
                del_page_from_lru_list(page, lruvec, lru);
                SetPageActive(page);
@@ -500,7 +500,7 @@ void lru_cache_add_inactive_or_unevictable(struct page *page,
                 * lock is held(spinlock), which implies preemption disabled.
                 */
                __mod_zone_page_state(page_zone(page), NR_MLOCK,
-                                   hpage_nr_pages(page));
+                                   thp_nr_pages(page));
                count_vm_event(UNEVICTABLE_PGMLOCKED);
        }
        lru_cache_add(page);
@@ -532,7 +532,7 @@ static void lru_deactivate_file_fn(struct page *page, struct lruvec *lruvec,
 {
        int lru;
        bool active;
-       int nr_pages = hpage_nr_pages(page);
+       int nr_pages = thp_nr_pages(page);
 
        if (!PageLRU(page))
                return;
@@ -580,7 +580,7 @@ static void lru_deactivate_fn(struct page *page, struct lruvec *lruvec,
 {
        if (PageLRU(page) && PageActive(page) && !PageUnevictable(page)) {
                int lru = page_lru_base_type(page);
-               int nr_pages = hpage_nr_pages(page);
+               int nr_pages = thp_nr_pages(page);
 
                del_page_from_lru_list(page, lruvec, lru + LRU_ACTIVE);
                ClearPageActive(page);
@@ -599,7 +599,7 @@ static void lru_lazyfree_fn(struct page *page, struct lruvec *lruvec,
        if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) &&
            !PageSwapCache(page) && !PageUnevictable(page)) {
                bool active = PageActive(page);
-               int nr_pages = hpage_nr_pages(page);
+               int nr_pages = thp_nr_pages(page);
 
                del_page_from_lru_list(page, lruvec,
                                       LRU_INACTIVE_ANON + active);
@@ -632,7 +632,8 @@ void lru_add_drain_cpu(int cpu)
                __pagevec_lru_add(pvec);
 
        pvec = &per_cpu(lru_rotate.pvec, cpu);
-       if (pagevec_count(pvec)) {
+       /* Disabling interrupts below acts as a compiler barrier. */
+       if (data_race(pagevec_count(pvec))) {
                unsigned long flags;
 
                /* No harm done if a racing interrupt already did this */
@@ -793,7 +794,7 @@ void lru_add_drain_all(void)
                struct work_struct *work = &per_cpu(lru_add_drain_work, cpu);
 
                if (pagevec_count(&per_cpu(lru_pvecs.lru_add, cpu)) ||
-                   pagevec_count(&per_cpu(lru_rotate.pvec, cpu)) ||
+                   data_race(pagevec_count(&per_cpu(lru_rotate.pvec, cpu))) ||
                    pagevec_count(&per_cpu(lru_pvecs.lru_deactivate_file, cpu)) ||
                    pagevec_count(&per_cpu(lru_pvecs.lru_deactivate, cpu)) ||
                    pagevec_count(&per_cpu(lru_pvecs.lru_lazyfree, cpu)) ||
@@ -972,7 +973,7 @@ static void __pagevec_lru_add_fn(struct page *page, struct lruvec *lruvec,
 {
        enum lru_list lru;
        int was_unevictable = TestClearPageUnevictable(page);
-       int nr_pages = hpage_nr_pages(page);
+       int nr_pages = thp_nr_pages(page);
 
        VM_BUG_ON_PAGE(PageLRU(page), page);
 
index b73aabd..c16eebb 100644 (file)
@@ -57,8 +57,8 @@ static bool enable_vma_readahead __read_mostly = true;
 #define GET_SWAP_RA_VAL(vma)                                   \
        (atomic_long_read(&(vma)->swap_readahead_info) ? : 4)
 
-#define INC_CACHE_INFO(x)      do { swap_cache_info.x++; } while (0)
-#define ADD_CACHE_INFO(x, nr)  do { swap_cache_info.x += (nr); } while (0)
+#define INC_CACHE_INFO(x)      data_race(swap_cache_info.x++)
+#define ADD_CACHE_INFO(x, nr)  data_race(swap_cache_info.x += (nr))
 
 static struct {
        unsigned long add_total;
@@ -130,7 +130,7 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry,
        struct address_space *address_space = swap_address_space(entry);
        pgoff_t idx = swp_offset(entry);
        XA_STATE_ORDER(xas, &address_space->i_pages, idx, compound_order(page));
-       unsigned long i, nr = hpage_nr_pages(page);
+       unsigned long i, nr = thp_nr_pages(page);
        void *old;
 
        VM_BUG_ON_PAGE(!PageLocked(page), page);
@@ -183,7 +183,7 @@ void __delete_from_swap_cache(struct page *page,
                        swp_entry_t entry, void *shadow)
 {
        struct address_space *address_space = swap_address_space(entry);
-       int i, nr = hpage_nr_pages(page);
+       int i, nr = thp_nr_pages(page);
        pgoff_t idx = swp_offset(entry);
        XA_STATE(xas, &address_space->i_pages, idx);
 
@@ -278,7 +278,7 @@ void delete_from_swap_cache(struct page *page)
        xa_unlock_irq(&address_space->i_pages);
 
        put_swap_page(page, entry);
-       page_ref_sub(page, hpage_nr_pages(page));
+       page_ref_sub(page, thp_nr_pages(page));
 }
 
 void clear_shadow_from_swap_cache(int type, unsigned long begin,
index e653eea..12f59e6 100644 (file)
@@ -672,7 +672,7 @@ static void swap_range_alloc(struct swap_info_struct *si, unsigned long offset,
        if (offset == si->lowest_bit)
                si->lowest_bit += nr_entries;
        if (end == si->highest_bit)
-               si->highest_bit -= nr_entries;
+               WRITE_ONCE(si->highest_bit, si->highest_bit - nr_entries);
        si->inuse_pages += nr_entries;
        if (si->inuse_pages == si->pages) {
                si->lowest_bit = si->max;
@@ -705,7 +705,7 @@ static void swap_range_free(struct swap_info_struct *si, unsigned long offset,
        if (end > si->highest_bit) {
                bool was_full = !si->highest_bit;
 
-               si->highest_bit = end;
+               WRITE_ONCE(si->highest_bit, end);
                if (was_full && (si->flags & SWP_WRITEOK))
                        add_to_avail_list(si);
        }
@@ -870,7 +870,7 @@ checks:
                else
                        goto done;
        }
-       si->swap_map[offset] = usage;
+       WRITE_ONCE(si->swap_map[offset], usage);
        inc_cluster_info_page(si, si->cluster_info, offset);
        unlock_cluster(ci);
 
@@ -929,12 +929,13 @@ done:
 
 scan:
        spin_unlock(&si->lock);
-       while (++offset <= si->highest_bit) {
-               if (!si->swap_map[offset]) {
+       while (++offset <= READ_ONCE(si->highest_bit)) {
+               if (data_race(!si->swap_map[offset])) {
                        spin_lock(&si->lock);
                        goto checks;
                }
-               if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
+               if (vm_swap_full() &&
+                   READ_ONCE(si->swap_map[offset]) == SWAP_HAS_CACHE) {
                        spin_lock(&si->lock);
                        goto checks;
                }
@@ -946,11 +947,12 @@ scan:
        }
        offset = si->lowest_bit;
        while (offset < scan_base) {
-               if (!si->swap_map[offset]) {
+               if (data_race(!si->swap_map[offset])) {
                        spin_lock(&si->lock);
                        goto checks;
                }
-               if (vm_swap_full() && si->swap_map[offset] == SWAP_HAS_CACHE) {
+               if (vm_swap_full() &&
+                   READ_ONCE(si->swap_map[offset]) == SWAP_HAS_CACHE) {
                        spin_lock(&si->lock);
                        goto checks;
                }
@@ -1149,7 +1151,7 @@ static struct swap_info_struct *__swap_info_get(swp_entry_t entry)
        p = swp_swap_info(entry);
        if (!p)
                goto bad_nofile;
-       if (!(p->flags & SWP_USED))
+       if (data_race(!(p->flags & SWP_USED)))
                goto bad_device;
        offset = swp_offset(entry);
        if (offset >= p->max)
@@ -1175,7 +1177,7 @@ static struct swap_info_struct *_swap_info_get(swp_entry_t entry)
        p = __swap_info_get(entry);
        if (!p)
                goto out;
-       if (!p->swap_map[swp_offset(entry)])
+       if (data_race(!p->swap_map[swp_offset(entry)]))
                goto bad_free;
        return p;
 
@@ -1244,7 +1246,10 @@ static unsigned char __swap_entry_free_locked(struct swap_info_struct *p,
        }
 
        usage = count | has_cache;
-       p->swap_map[offset] = usage ? : SWAP_HAS_CACHE;
+       if (usage)
+               WRITE_ONCE(p->swap_map[offset], usage);
+       else
+               WRITE_ONCE(p->swap_map[offset], SWAP_HAS_CACHE);
 
        return usage;
 }
@@ -1296,7 +1301,7 @@ struct swap_info_struct *get_swap_device(swp_entry_t entry)
                goto bad_nofile;
 
        rcu_read_lock();
-       if (!(si->flags & SWP_VALID))
+       if (data_race(!(si->flags & SWP_VALID)))
                goto unlock_out;
        offset = swp_offset(entry);
        if (offset >= si->max)
@@ -1370,7 +1375,7 @@ void put_swap_page(struct page *page, swp_entry_t entry)
        unsigned char *map;
        unsigned int i, free_entries = 0;
        unsigned char val;
-       int size = swap_entry_size(hpage_nr_pages(page));
+       int size = swap_entry_size(thp_nr_pages(page));
 
        si = _swap_info_get(entry);
        if (!si)
@@ -3484,7 +3489,7 @@ static int __swap_duplicate(swp_entry_t entry, unsigned char usage)
        } else
                err = -ENOENT;                  /* unused swap entry */
 
-       p->swap_map[offset] = count | has_cache;
+       WRITE_ONCE(p->swap_map[offset], count | has_cache);
 
 unlock_out:
        unlock_cluster_or_swap_info(p, ci);
index 738115e..99e1796 100644 (file)
@@ -1354,7 +1354,7 @@ static unsigned int shrink_page_list(struct list_head *page_list,
                        case PAGE_ACTIVATE:
                                goto activate_locked;
                        case PAGE_SUCCESS:
-                               stat->nr_pageout += hpage_nr_pages(page);
+                               stat->nr_pageout += thp_nr_pages(page);
 
                                if (PageWriteback(page))
                                        goto keep;
@@ -1862,7 +1862,7 @@ static unsigned noinline_for_stack move_pages_to_lru(struct lruvec *lruvec,
                SetPageLRU(page);
                lru = page_lru(page);
 
-               nr_pages = hpage_nr_pages(page);
+               nr_pages = thp_nr_pages(page);
                update_lru_size(lruvec, lru, page_zonenum(page), nr_pages);
                list_move(&page->lru, &lruvec->lists[lru]);
 
@@ -2065,7 +2065,7 @@ static void shrink_active_list(unsigned long nr_to_scan,
                         * so we ignore them here.
                         */
                        if ((vm_flags & VM_EXEC) && page_is_file_lru(page)) {
-                               nr_rotated += hpage_nr_pages(page);
+                               nr_rotated += thp_nr_pages(page);
                                list_add(&page->lru, &l_active);
                                continue;
                        }
index 727a26d..e670f91 100644 (file)
@@ -1642,12 +1642,6 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
                   zone->present_pages,
                   zone_managed_pages(zone));
 
-       /* If unpopulated, no other information is useful */
-       if (!populated_zone(zone)) {
-               seq_putc(m, '\n');
-               return;
-       }
-
        seq_printf(m,
                   "\n        protection: (%ld",
                   zone->lowmem_reserve[0]);
@@ -1655,6 +1649,12 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
                seq_printf(m, ", %ld", zone->lowmem_reserve[i]);
        seq_putc(m, ')');
 
+       /* If unpopulated, no other information is useful */
+       if (!populated_zone(zone)) {
+               seq_putc(m, '\n');
+               return;
+       }
+
        for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
                seq_printf(m, "\n      %-12s %lu", zone_stat_name(i),
                           zone_page_state(zone, i));
index 8cbe4e3..92e6611 100644 (file)
@@ -263,7 +263,7 @@ void *workingset_eviction(struct page *page, struct mem_cgroup *target_memcg)
        VM_BUG_ON_PAGE(!PageLocked(page), page);
 
        lruvec = mem_cgroup_lruvec(target_memcg, pgdat);
-       workingset_age_nonresident(lruvec, hpage_nr_pages(page));
+       workingset_age_nonresident(lruvec, thp_nr_pages(page));
        /* XXX: target_memcg can be NULL, go through lruvec */
        memcgid = mem_cgroup_id(lruvec_memcg(lruvec));
        eviction = atomic_long_read(&lruvec->nonresident_age);
@@ -374,7 +374,7 @@ void workingset_refault(struct page *page, void *shadow)
                goto out;
 
        SetPageActive(page);
-       workingset_age_nonresident(lruvec, hpage_nr_pages(page));
+       workingset_age_nonresident(lruvec, thp_nr_pages(page));
        inc_lruvec_state(lruvec, WORKINGSET_ACTIVATE_BASE + file);
 
        /* Page was active prior to eviction */
@@ -411,7 +411,7 @@ void workingset_activation(struct page *page)
        if (!mem_cgroup_disabled() && !memcg)
                goto out;
        lruvec = mem_cgroup_page_lruvec(page, page_pgdat(page));
-       workingset_age_nonresident(lruvec, hpage_nr_pages(page));
+       workingset_age_nonresident(lruvec, thp_nr_pages(page));
 out:
        rcu_read_unlock();
 }
index 12ecacf..c0762a3 100644 (file)
@@ -950,7 +950,7 @@ static int p9_bind_privport(struct socket *sock)
 
        memset(&cl, 0, sizeof(cl));
        cl.sin_family = AF_INET;
-       cl.sin_addr.s_addr = INADDR_ANY;
+       cl.sin_addr.s_addr = htonl(INADDR_ANY);
        for (port = p9_ipport_resv_max; port >= p9_ipport_resv_min; port--) {
                cl.sin_port = htons((ushort)port);
                err = kernel_bind(sock, (struct sockaddr *)&cl, sizeof(cl));
index 1641f41..ebe33b6 100644 (file)
@@ -2238,6 +2238,10 @@ static int compat_do_ebt_get_ctl(struct sock *sk, int cmd,
        struct ebt_table *t;
        struct net *net = sock_net(sk);
 
+       if ((cmd == EBT_SO_GET_INFO || cmd == EBT_SO_GET_INIT_INFO) &&
+           *len != sizeof(struct compat_ebt_replace))
+               return -EINVAL;
+
        if (copy_from_user(&tmp, user, sizeof(tmp)))
                return -EFAULT;
 
index 8096732..8d033a7 100644 (file)
@@ -168,6 +168,7 @@ static unsigned int nf_ct_br_defrag4(struct sk_buff *skb,
 static unsigned int nf_ct_br_defrag6(struct sk_buff *skb,
                                     const struct nf_hook_state *state)
 {
+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
        u16 zone_id = NF_CT_DEFAULT_ZONE_ID;
        enum ip_conntrack_info ctinfo;
        struct br_input_skb_cb cb;
@@ -180,14 +181,17 @@ static unsigned int nf_ct_br_defrag6(struct sk_buff *skb,
 
        br_skb_cb_save(skb, &cb, sizeof(struct inet6_skb_parm));
 
-       err = nf_ipv6_br_defrag(state->net, skb,
-                               IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone_id);
+       err = nf_ct_frag6_gather(state->net, skb,
+                                IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone_id);
        /* queued */
        if (err == -EINPROGRESS)
                return NF_STOLEN;
 
        br_skb_cb_restore(skb, &cb, IP6CB(skb)->frag_max_size);
        return err == 0 ? NF_ACCEPT : NF_DROP;
+#else
+       return NF_ACCEPT;
+#endif
 }
 
 static int nf_ct_br_ip_check(const struct sk_buff *skb)
index 78ff9b3..b93876c 100644 (file)
@@ -398,6 +398,7 @@ static int j1939_sk_init(struct sock *sk)
        spin_lock_init(&jsk->sk_session_queue_lock);
        INIT_LIST_HEAD(&jsk->sk_session_queue);
        sk->sk_destruct = j1939_sk_sock_destruct;
+       sk->sk_protocol = CAN_J1939;
 
        return 0;
 }
@@ -466,6 +467,14 @@ static int j1939_sk_bind(struct socket *sock, struct sockaddr *uaddr, int len)
                        goto out_release_sock;
                }
 
+               if (!ndev->ml_priv) {
+                       netdev_warn_once(ndev,
+                                        "No CAN mid layer private allocated, please fix your driver and use alloc_candev()!\n");
+                       dev_put(ndev);
+                       ret = -ENODEV;
+                       goto out_release_sock;
+               }
+
                priv = j1939_netdev_start(ndev);
                dev_put(ndev);
                if (IS_ERR(priv)) {
@@ -553,6 +562,11 @@ static int j1939_sk_connect(struct socket *sock, struct sockaddr *uaddr,
 static void j1939_sk_sock2sockaddr_can(struct sockaddr_can *addr,
                                       const struct j1939_sock *jsk, int peer)
 {
+       /* There are two holes (2 bytes and 3 bytes) to clear to avoid
+        * leaking kernel information to user space.
+        */
+       memset(addr, 0, J1939_MIN_NAMELEN);
+
        addr->can_family = AF_CAN;
        addr->can_ifindex = jsk->ifindex;
        addr->can_addr.j1939.pgn = jsk->addr.pgn;
index 9f99af5..a8dd956 100644 (file)
@@ -352,17 +352,16 @@ void j1939_session_skb_queue(struct j1939_session *session,
        skb_queue_tail(&session->skb_queue, skb);
 }
 
-static struct sk_buff *j1939_session_skb_find(struct j1939_session *session)
+static struct
+sk_buff *j1939_session_skb_find_by_offset(struct j1939_session *session,
+                                         unsigned int offset_start)
 {
        struct j1939_priv *priv = session->priv;
+       struct j1939_sk_buff_cb *do_skcb;
        struct sk_buff *skb = NULL;
        struct sk_buff *do_skb;
-       struct j1939_sk_buff_cb *do_skcb;
-       unsigned int offset_start;
        unsigned long flags;
 
-       offset_start = session->pkt.dpo * 7;
-
        spin_lock_irqsave(&session->skb_queue.lock, flags);
        skb_queue_walk(&session->skb_queue, do_skb) {
                do_skcb = j1939_skb_to_cb(do_skb);
@@ -382,6 +381,14 @@ static struct sk_buff *j1939_session_skb_find(struct j1939_session *session)
        return skb;
 }
 
+static struct sk_buff *j1939_session_skb_find(struct j1939_session *session)
+{
+       unsigned int offset_start;
+
+       offset_start = session->pkt.dpo * 7;
+       return j1939_session_skb_find_by_offset(session, offset_start);
+}
+
 /* see if we are receiver
  * returns 0 for broadcasts, although we will receive them
  */
@@ -716,10 +723,12 @@ static int j1939_session_tx_rts(struct j1939_session *session)
                return ret;
 
        session->last_txcmd = dat[0];
-       if (dat[0] == J1939_TP_CMD_BAM)
+       if (dat[0] == J1939_TP_CMD_BAM) {
                j1939_tp_schedule_txtimer(session, 50);
-
-       j1939_tp_set_rxtimeout(session, 1250);
+               j1939_tp_set_rxtimeout(session, 250);
+       } else {
+               j1939_tp_set_rxtimeout(session, 1250);
+       }
 
        netdev_dbg(session->priv->ndev, "%s: 0x%p\n", __func__, session);
 
@@ -766,7 +775,7 @@ static int j1939_session_tx_dat(struct j1939_session *session)
        int ret = 0;
        u8 dat[8];
 
-       se_skb = j1939_session_skb_find(session);
+       se_skb = j1939_session_skb_find_by_offset(session, session->pkt.tx * 7);
        if (!se_skb)
                return -ENOBUFS;
 
@@ -787,6 +796,18 @@ static int j1939_session_tx_dat(struct j1939_session *session)
                if (len > 7)
                        len = 7;
 
+               if (offset + len > se_skb->len) {
+                       netdev_err_once(priv->ndev,
+                                       "%s: 0x%p: requested data outside of queued buffer: offset %i, len %i, pkt.tx: %i\n",
+                                       __func__, session, skcb->offset, se_skb->len , session->pkt.tx);
+                       return -EOVERFLOW;
+               }
+
+               if (!len) {
+                       ret = -ENOBUFS;
+                       break;
+               }
+
                memcpy(&dat[1], &tpdat[offset], len);
                ret = j1939_tp_tx_dat(session, dat, len + 1);
                if (ret < 0) {
@@ -1055,9 +1076,9 @@ static void __j1939_session_cancel(struct j1939_session *session,
        lockdep_assert_held(&session->priv->active_session_list_lock);
 
        session->err = j1939_xtp_abort_to_errno(priv, err);
+       session->state = J1939_SESSION_WAITING_ABORT;
        /* do not send aborts on incoming broadcasts */
        if (!j1939_cb_is_broadcast(&session->skcb)) {
-               session->state = J1939_SESSION_WAITING_ABORT;
                j1939_xtp_tx_abort(priv, &session->skcb,
                                   !session->transmission,
                                   err, session->skcb.addr.pgn);
@@ -1120,6 +1141,9 @@ static enum hrtimer_restart j1939_tp_txtimer(struct hrtimer *hrtimer)
                 * cleanup including propagation of the error to user space.
                 */
                break;
+       case -EOVERFLOW:
+               j1939_session_cancel(session, J1939_XTP_ABORT_ECTS_TOO_BIG);
+               break;
        case 0:
                session->tx_retry = 0;
                break;
@@ -1651,8 +1675,12 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
                        return;
                }
                session = j1939_xtp_rx_rts_session_new(priv, skb);
-               if (!session)
+               if (!session) {
+                       if (cmd == J1939_TP_CMD_BAM && j1939_sk_recv_match(priv, skcb))
+                               netdev_info(priv->ndev, "%s: failed to create TP BAM session\n",
+                                           __func__);
                        return;
+               }
        } else {
                if (j1939_xtp_rx_rts_session_active(session, skb)) {
                        j1939_session_put(session);
@@ -1661,11 +1689,15 @@ static void j1939_xtp_rx_rts(struct j1939_priv *priv, struct sk_buff *skb,
        }
        session->last_cmd = cmd;
 
-       j1939_tp_set_rxtimeout(session, 1250);
-
-       if (cmd != J1939_TP_CMD_BAM && !session->transmission) {
-               j1939_session_txtimer_cancel(session);
-               j1939_tp_schedule_txtimer(session, 0);
+       if (cmd == J1939_TP_CMD_BAM) {
+               if (!session->transmission)
+                       j1939_tp_set_rxtimeout(session, 750);
+       } else {
+               if (!session->transmission) {
+                       j1939_session_txtimer_cancel(session);
+                       j1939_tp_schedule_txtimer(session, 0);
+               }
+               j1939_tp_set_rxtimeout(session, 1250);
        }
 
        j1939_session_put(session);
@@ -1716,6 +1748,7 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
        int offset;
        int nbytes;
        bool final = false;
+       bool remain = false;
        bool do_cts_eoma = false;
        int packet;
 
@@ -1750,7 +1783,8 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
                            __func__, session);
                goto out_session_cancel;
        }
-       se_skb = j1939_session_skb_find(session);
+
+       se_skb = j1939_session_skb_find_by_offset(session, packet * 7);
        if (!se_skb) {
                netdev_warn(priv->ndev, "%s: 0x%p: no skb found\n", __func__,
                            session);
@@ -1769,7 +1803,20 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
        }
 
        tpdat = se_skb->data;
-       memcpy(&tpdat[offset], &dat[1], nbytes);
+       if (!session->transmission) {
+               memcpy(&tpdat[offset], &dat[1], nbytes);
+       } else {
+               int err;
+
+               err = memcmp(&tpdat[offset], &dat[1], nbytes);
+               if (err)
+                       netdev_err_once(priv->ndev,
+                                       "%s: 0x%p: Data of RX-looped back packet (%*ph) doesn't match TX data (%*ph)!\n",
+                                       __func__, session,
+                                       nbytes, &dat[1],
+                                       nbytes, &tpdat[offset]);
+       }
+
        if (packet == session->pkt.rx)
                session->pkt.rx++;
 
@@ -1777,6 +1824,8 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
            j1939_cb_is_broadcast(&session->skcb)) {
                if (session->pkt.rx >= session->pkt.total)
                        final = true;
+               else
+                       remain = true;
        } else {
                /* never final, an EOMA must follow */
                if (session->pkt.rx >= session->pkt.last)
@@ -1784,7 +1833,11 @@ static void j1939_xtp_rx_dat_one(struct j1939_session *session,
        }
 
        if (final) {
+               j1939_session_timers_cancel(session);
                j1939_session_completed(session);
+       } else if (remain) {
+               if (!session->transmission)
+                       j1939_tp_set_rxtimeout(session, 750);
        } else if (do_cts_eoma) {
                j1939_tp_set_rxtimeout(session, 1250);
                if (!session->transmission)
@@ -1829,6 +1882,13 @@ static void j1939_xtp_rx_dat(struct j1939_priv *priv, struct sk_buff *skb)
                else
                        j1939_xtp_rx_dat_one(session, skb);
        }
+
+       if (j1939_cb_is_broadcast(skcb)) {
+               session = j1939_session_get_by_addr(priv, &skcb->addr, false,
+                                                   false);
+               if (session)
+                       j1939_xtp_rx_dat_one(session, skb);
+       }
 }
 
 /* j1939 main intf */
@@ -1920,7 +1980,7 @@ static void j1939_tp_cmd_recv(struct j1939_priv *priv, struct sk_buff *skb)
                if (j1939_tp_im_transmitter(skcb))
                        j1939_xtp_rx_rts(priv, skb, true);
 
-               if (j1939_tp_im_receiver(skcb))
+               if (j1939_tp_im_receiver(skcb) || j1939_cb_is_broadcast(skcb))
                        j1939_xtp_rx_rts(priv, skb, false);
 
                break;
@@ -1984,7 +2044,7 @@ int j1939_tp_recv(struct j1939_priv *priv, struct sk_buff *skb)
 {
        struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
 
-       if (!j1939_tp_im_involved_anydir(skcb))
+       if (!j1939_tp_im_involved_anydir(skcb) && !j1939_cb_is_broadcast(skcb))
                return 0;
 
        switch (skcb->addr.pgn) {
@@ -2017,6 +2077,10 @@ void j1939_simple_recv(struct j1939_priv *priv, struct sk_buff *skb)
        if (!skb->sk)
                return;
 
+       if (skb->sk->sk_family != AF_CAN ||
+           skb->sk->sk_protocol != CAN_J1939)
+               return;
+
        j1939_session_list_lock(priv);
        session = j1939_session_get_simple(priv, skb);
        j1939_session_list_unlock(priv);
index 7df6c96..b5d1129 100644 (file)
@@ -8913,10 +8913,6 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
                NL_SET_ERR_MSG(extack, "Active program does not match expected");
                return -EEXIST;
        }
-       if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST) && cur_prog) {
-               NL_SET_ERR_MSG(extack, "XDP program already attached");
-               return -EBUSY;
-       }
 
        /* put effective new program into new_prog */
        if (link)
@@ -8927,6 +8923,10 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
                enum bpf_xdp_mode other_mode = mode == XDP_MODE_SKB
                                               ? XDP_MODE_DRV : XDP_MODE_SKB;
 
+               if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST) && cur_prog) {
+                       NL_SET_ERR_MSG(extack, "XDP program already attached");
+                       return -EBUSY;
+               }
                if (!offload && dev_xdp_prog(dev, other_mode)) {
                        NL_SET_ERR_MSG(extack, "Native and generic XDP can't be active at the same time");
                        return -EEXIST;
index e674f0f..e5feb87 100644 (file)
@@ -4063,7 +4063,7 @@ static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
 {
        lockdep_assert_held(&devlink->lock);
 
-       if (WARN_ON(xa_load(&devlink->snapshot_ids, id)))
+       if (xa_load(&devlink->snapshot_ids, id))
                return -EEXIST;
 
        return xa_err(xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
index 7124f0f..b2df520 100644 (file)
@@ -8317,15 +8317,31 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
 /* Helper macro for adding read access to tcp_sock or sock fields. */
 #define SOCK_OPS_GET_FIELD(BPF_FIELD, OBJ_FIELD, OBJ)                        \
        do {                                                                  \
+               int fullsock_reg = si->dst_reg, reg = BPF_REG_9, jmp = 2;     \
                BUILD_BUG_ON(sizeof_field(OBJ, OBJ_FIELD) >                   \
                             sizeof_field(struct bpf_sock_ops, BPF_FIELD));   \
+               if (si->dst_reg == reg || si->src_reg == reg)                 \
+                       reg--;                                                \
+               if (si->dst_reg == reg || si->src_reg == reg)                 \
+                       reg--;                                                \
+               if (si->dst_reg == si->src_reg) {                             \
+                       *insn++ = BPF_STX_MEM(BPF_DW, si->src_reg, reg,       \
+                                         offsetof(struct bpf_sock_ops_kern,  \
+                                         temp));                             \
+                       fullsock_reg = reg;                                   \
+                       jmp += 2;                                             \
+               }                                                             \
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(                       \
                                                struct bpf_sock_ops_kern,     \
                                                is_fullsock),                 \
-                                     si->dst_reg, si->src_reg,               \
+                                     fullsock_reg, si->src_reg,              \
                                      offsetof(struct bpf_sock_ops_kern,      \
                                               is_fullsock));                 \
-               *insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 2);            \
+               *insn++ = BPF_JMP_IMM(BPF_JEQ, fullsock_reg, 0, jmp);         \
+               if (si->dst_reg == si->src_reg)                               \
+                       *insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,       \
+                                     offsetof(struct bpf_sock_ops_kern,      \
+                                     temp));                                 \
                *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(                       \
                                                struct bpf_sock_ops_kern, sk),\
                                      si->dst_reg, si->src_reg,               \
@@ -8334,6 +8350,49 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                                                       OBJ_FIELD),            \
                                      si->dst_reg, si->dst_reg,               \
                                      offsetof(OBJ, OBJ_FIELD));              \
+               if (si->dst_reg == si->src_reg) {                             \
+                       *insn++ = BPF_JMP_A(1);                               \
+                       *insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,       \
+                                     offsetof(struct bpf_sock_ops_kern,      \
+                                     temp));                                 \
+               }                                                             \
+       } while (0)
+
+#define SOCK_OPS_GET_SK()                                                            \
+       do {                                                                  \
+               int fullsock_reg = si->dst_reg, reg = BPF_REG_9, jmp = 1;     \
+               if (si->dst_reg == reg || si->src_reg == reg)                 \
+                       reg--;                                                \
+               if (si->dst_reg == reg || si->src_reg == reg)                 \
+                       reg--;                                                \
+               if (si->dst_reg == si->src_reg) {                             \
+                       *insn++ = BPF_STX_MEM(BPF_DW, si->src_reg, reg,       \
+                                         offsetof(struct bpf_sock_ops_kern,  \
+                                         temp));                             \
+                       fullsock_reg = reg;                                   \
+                       jmp += 2;                                             \
+               }                                                             \
+               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(                       \
+                                               struct bpf_sock_ops_kern,     \
+                                               is_fullsock),                 \
+                                     fullsock_reg, si->src_reg,              \
+                                     offsetof(struct bpf_sock_ops_kern,      \
+                                              is_fullsock));                 \
+               *insn++ = BPF_JMP_IMM(BPF_JEQ, fullsock_reg, 0, jmp);         \
+               if (si->dst_reg == si->src_reg)                               \
+                       *insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,       \
+                                     offsetof(struct bpf_sock_ops_kern,      \
+                                     temp));                                 \
+               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(                       \
+                                               struct bpf_sock_ops_kern, sk),\
+                                     si->dst_reg, si->src_reg,               \
+                                     offsetof(struct bpf_sock_ops_kern, sk));\
+               if (si->dst_reg == si->src_reg) {                             \
+                       *insn++ = BPF_JMP_A(1);                               \
+                       *insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,       \
+                                     offsetof(struct bpf_sock_ops_kern,      \
+                                     temp));                                 \
+               }                                                             \
        } while (0)
 
 #define SOCK_OPS_GET_TCP_SOCK_FIELD(FIELD) \
@@ -8620,17 +8679,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
                SOCK_OPS_GET_TCP_SOCK_FIELD(bytes_acked);
                break;
        case offsetof(struct bpf_sock_ops, sk):
-               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
-                                               struct bpf_sock_ops_kern,
-                                               is_fullsock),
-                                     si->dst_reg, si->src_reg,
-                                     offsetof(struct bpf_sock_ops_kern,
-                                              is_fullsock));
-               *insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 1);
-               *insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
-                                               struct bpf_sock_ops_kern, sk),
-                                     si->dst_reg, si->src_reg,
-                                     offsetof(struct bpf_sock_ops_kern, sk));
+               SOCK_OPS_GET_SK();
                break;
        }
        return insn - insn_buf;
index 7e2e502..5c3b906 100644 (file)
@@ -5418,8 +5418,8 @@ struct sk_buff *skb_vlan_untag(struct sk_buff *skb)
        skb = skb_share_check(skb, GFP_ATOMIC);
        if (unlikely(!skb))
                goto err_free;
-
-       if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
+       /* We may access the two bytes after vlan_hdr in vlan_set_encap_proto(). */
+       if (unlikely(!pskb_may_pull(skb, VLAN_HLEN + sizeof(unsigned short))))
                goto err_free;
 
        vhdr = (struct vlan_hdr *)skb->data;
index 409e79b..6d0e942 100644 (file)
@@ -245,9 +245,6 @@ static const struct nf_ipv6_ops ipv6ops = {
        .route_input            = ip6_route_input,
        .fragment               = ip6_fragment,
        .reroute                = nf_ip6_reroute,
-#if IS_MODULE(CONFIG_IPV6) && IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
-       .br_defrag              = nf_ct_frag6_gather,
-#endif
 #if IS_MODULE(CONFIG_IPV6)
        .br_fragment            = br_ip6_fragment,
 #endif
index 8c1d1a5..1aad411 100644 (file)
@@ -725,8 +725,10 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
                if (!psize)
                        return -EINVAL;
 
-               if (!sk_wmem_schedule(sk, psize + dfrag->overhead))
+               if (!sk_wmem_schedule(sk, psize + dfrag->overhead)) {
+                       iov_iter_revert(&msg->msg_iter, psize);
                        return -ENOMEM;
+               }
        } else {
                offset = dfrag->offset;
                psize = min_t(size_t, dfrag->data_len, avail_size);
@@ -737,8 +739,11 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
         */
        ret = do_tcp_sendpages(ssk, page, offset, psize,
                               msg->msg_flags | MSG_SENDPAGE_NOTLAST | MSG_DONTWAIT);
-       if (ret <= 0)
+       if (ret <= 0) {
+               if (!retransmission)
+                       iov_iter_revert(&msg->msg_iter, psize);
                return ret;
+       }
 
        frag_truesize += ret;
        if (!retransmission) {
@@ -1388,7 +1393,9 @@ static void mptcp_worker(struct work_struct *work)
        struct mptcp_data_frag *dfrag;
        u64 orig_write_seq;
        size_t copied = 0;
-       struct msghdr msg;
+       struct msghdr msg = {
+               .msg_flags = MSG_DONTWAIT,
+       };
        long timeo = 0;
 
        lock_sock(sk);
@@ -1421,7 +1428,6 @@ static void mptcp_worker(struct work_struct *work)
 
        lock_sock(ssk);
 
-       msg.msg_flags = MSG_DONTWAIT;
        orig_len = dfrag->data_len;
        orig_offset = dfrag->offset;
        orig_write_seq = dfrag->data_seq;
index d878e34..fd814e5 100644 (file)
@@ -2018,8 +2018,10 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
        if (nla[NFTA_CHAIN_NAME]) {
                chain->name = nla_strdup(nla[NFTA_CHAIN_NAME], GFP_KERNEL);
        } else {
-               if (!(flags & NFT_CHAIN_BINDING))
-                       return -EINVAL;
+               if (!(flags & NFT_CHAIN_BINDING)) {
+                       err = -EINVAL;
+                       goto err1;
+               }
 
                snprintf(name, sizeof(name), "__chain%llu", ++chain_id);
                chain->name = kstrdup(name, GFP_KERNEL);
index 6428856..8e56f35 100644 (file)
@@ -27,8 +27,6 @@ struct nft_xt_match_priv {
        void *info;
 };
 
-static refcount_t nft_compat_pending_destroy = REFCOUNT_INIT(1);
-
 static int nft_compat_chain_validate_dependency(const struct nft_ctx *ctx,
                                                const char *tablename)
 {
@@ -215,6 +213,17 @@ static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv)
        return 0;
 }
 
+static void nft_compat_wait_for_destructors(void)
+{
+       /* xtables matches or targets can have side effects, e.g.
+        * creation/destruction of /proc files.
+        * The xt ->destroy functions are run asynchronously from
+        * work queue.  If we have pending invocations we thus
+        * need to wait for those to finish.
+        */
+       nf_tables_trans_destroy_flush_work();
+}
+
 static int
 nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
                const struct nlattr * const tb[])
@@ -238,14 +247,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 
        nft_target_set_tgchk_param(&par, ctx, target, info, &e, proto, inv);
 
-       /* xtables matches or targets can have side effects, e.g.
-        * creation/destruction of /proc files.
-        * The xt ->destroy functions are run asynchronously from
-        * work queue.  If we have pending invocations we thus
-        * need to wait for those to finish.
-        */
-       if (refcount_read(&nft_compat_pending_destroy) > 1)
-               nf_tables_trans_destroy_flush_work();
+       nft_compat_wait_for_destructors();
 
        ret = xt_check_target(&par, size, proto, inv);
        if (ret < 0)
@@ -260,7 +262,6 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 
 static void __nft_mt_tg_destroy(struct module *me, const struct nft_expr *expr)
 {
-       refcount_dec(&nft_compat_pending_destroy);
        module_put(me);
        kfree(expr->ops);
 }
@@ -468,6 +469,8 @@ __nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 
        nft_match_set_mtchk_param(&par, ctx, match, info, &e, proto, inv);
 
+       nft_compat_wait_for_destructors();
+
        return xt_check_match(&par, size, proto, inv);
 }
 
@@ -716,14 +719,6 @@ static const struct nfnetlink_subsystem nfnl_compat_subsys = {
 
 static struct nft_expr_type nft_match_type;
 
-static void nft_mt_tg_deactivate(const struct nft_ctx *ctx,
-                                const struct nft_expr *expr,
-                                enum nft_trans_phase phase)
-{
-       if (phase == NFT_TRANS_COMMIT)
-               refcount_inc(&nft_compat_pending_destroy);
-}
-
 static const struct nft_expr_ops *
 nft_match_select_ops(const struct nft_ctx *ctx,
                     const struct nlattr * const tb[])
@@ -762,7 +757,6 @@ nft_match_select_ops(const struct nft_ctx *ctx,
        ops->type = &nft_match_type;
        ops->eval = nft_match_eval;
        ops->init = nft_match_init;
-       ops->deactivate = nft_mt_tg_deactivate,
        ops->destroy = nft_match_destroy;
        ops->dump = nft_match_dump;
        ops->validate = nft_match_validate;
@@ -853,7 +847,6 @@ nft_target_select_ops(const struct nft_ctx *ctx,
        ops->size = NFT_EXPR_SIZE(XT_ALIGN(target->targetsize));
        ops->init = nft_target_init;
        ops->destroy = nft_target_destroy;
-       ops->deactivate = nft_mt_tg_deactivate,
        ops->dump = nft_target_dump;
        ops->validate = nft_target_validate;
        ops->data = target;
@@ -917,8 +910,6 @@ static void __exit nft_compat_module_exit(void)
        nfnetlink_subsys_unregister(&nfnl_compat_subsys);
        nft_unregister_expr(&nft_target_type);
        nft_unregister_expr(&nft_match_type);
-
-       WARN_ON_ONCE(refcount_read(&nft_compat_pending_destroy) != 1);
 }
 
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_NFT_COMPAT);
index 0778283..3c48cdc 100644 (file)
@@ -44,7 +44,7 @@ static void nft_exthdr_ipv6_eval(const struct nft_expr *expr,
 
        err = ipv6_find_hdr(pkt->skb, &offset, priv->type, NULL, NULL);
        if (priv->flags & NFT_EXTHDR_F_PRESENT) {
-               *dest = (err >= 0);
+               nft_reg_store8(dest, err >= 0);
                return;
        } else if (err < 0) {
                goto err;
@@ -141,7 +141,7 @@ static void nft_exthdr_ipv4_eval(const struct nft_expr *expr,
 
        err = ipv4_find_option(nft_net(pkt), skb, &offset, priv->type);
        if (priv->flags & NFT_EXTHDR_F_PRESENT) {
-               *dest = (err >= 0);
+               nft_reg_store8(dest, err >= 0);
                return;
        } else if (err < 0) {
                goto err;
index b4c0db0..90c558f 100644 (file)
@@ -692,23 +692,25 @@ static void qrtr_port_remove(struct qrtr_sock *ipc)
  */
 static int qrtr_port_assign(struct qrtr_sock *ipc, int *port)
 {
+       u32 min_port;
        int rc;
 
        mutex_lock(&qrtr_port_lock);
        if (!*port) {
-               rc = idr_alloc(&qrtr_ports, ipc,
-                              QRTR_MIN_EPH_SOCKET, QRTR_MAX_EPH_SOCKET + 1,
-                              GFP_ATOMIC);
-               if (rc >= 0)
-                       *port = rc;
+               min_port = QRTR_MIN_EPH_SOCKET;
+               rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, QRTR_MAX_EPH_SOCKET, GFP_ATOMIC);
+               if (!rc)
+                       *port = min_port;
        } else if (*port < QRTR_MIN_EPH_SOCKET && !capable(CAP_NET_ADMIN)) {
                rc = -EACCES;
        } else if (*port == QRTR_PORT_CTRL) {
-               rc = idr_alloc(&qrtr_ports, ipc, 0, 1, GFP_ATOMIC);
+               min_port = 0;
+               rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, 0, GFP_ATOMIC);
        } else {
-               rc = idr_alloc(&qrtr_ports, ipc, *port, *port + 1, GFP_ATOMIC);
-               if (rc >= 0)
-                       *port = rc;
+               min_port = *port;
+               rc = idr_alloc_u32(&qrtr_ports, ipc, &min_port, *port, GFP_ATOMIC);
+               if (!rc)
+                       *port = min_port;
        }
        mutex_unlock(&qrtr_port_lock);
 
index e9d0953..eadc0ed 100644 (file)
@@ -1510,6 +1510,6 @@ err_notifier:
 void unregister_rpc_pipefs(void)
 {
        rpc_clients_notifier_unregister();
-       kmem_cache_destroy(rpc_inode_cachep);
        unregister_filesystem(&rpc_pipe_fs_type);
+       kmem_cache_destroy(rpc_inode_cachep);
 }
index d5cc5db..6ba9d58 100644 (file)
@@ -607,6 +607,11 @@ static void xprt_reset_majortimeo(struct rpc_rqst *req)
        req->rq_majortimeo += xprt_calc_majortimeo(req);
 }
 
+static void xprt_reset_minortimeo(struct rpc_rqst *req)
+{
+       req->rq_minortimeo += req->rq_timeout;
+}
+
 static void xprt_init_majortimeo(struct rpc_task *task, struct rpc_rqst *req)
 {
        unsigned long time_init;
@@ -618,6 +623,7 @@ static void xprt_init_majortimeo(struct rpc_task *task, struct rpc_rqst *req)
                time_init = xprt_abs_ktime_to_jiffies(task->tk_start);
        req->rq_timeout = task->tk_client->cl_timeout->to_initval;
        req->rq_majortimeo = time_init + xprt_calc_majortimeo(req);
+       req->rq_minortimeo = time_init + req->rq_timeout;
 }
 
 /**
@@ -631,6 +637,8 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
        const struct rpc_timeout *to = req->rq_task->tk_client->cl_timeout;
        int status = 0;
 
+       if (time_before(jiffies, req->rq_minortimeo))
+               return status;
        if (time_before(jiffies, req->rq_majortimeo)) {
                if (to->to_exponential)
                        req->rq_timeout <<= 1;
@@ -649,6 +657,7 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
                spin_unlock(&xprt->transport_lock);
                status = -ETIMEDOUT;
        }
+       xprt_reset_minortimeo(req);
 
        if (req->rq_timeout == 0) {
                printk(KERN_WARNING "xprt_adjust_timeout: rq_timeout = 0!\n");
index 9dd7802..be1c400 100644 (file)
@@ -6,6 +6,7 @@
 menuconfig TIPC
        tristate "The TIPC Protocol"
        depends on INET
+       depends on IPV6 || IPV6=n
        help
          The Transparent Inter Process Communication (TIPC) protocol is
          specially designed for intra cluster communication. This protocol
index 2175163..90e3c70 100644 (file)
@@ -275,8 +275,9 @@ err_out:
 static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
                                 struct tipc_nl_compat_msg *msg)
 {
-       int err;
+       struct nlmsghdr *nlh;
        struct sk_buff *arg;
+       int err;
 
        if (msg->req_type && (!msg->req_size ||
                              !TLV_CHECK_TYPE(msg->req, msg->req_type)))
@@ -305,6 +306,15 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
                return -ENOMEM;
        }
 
+       nlh = nlmsg_put(arg, 0, 0, tipc_genl_family.id, 0, NLM_F_MULTI);
+       if (!nlh) {
+               kfree_skb(arg);
+               kfree_skb(msg->rep);
+               msg->rep = NULL;
+               return -EMSGSIZE;
+       }
+       nlmsg_end(arg, nlh);
+
        err = __tipc_nl_compat_dumpit(cmd, msg, arg);
        if (err) {
                kfree_skb(msg->rep);
index 00a10a2..1548f9c 100755 (executable)
@@ -34,7 +34,7 @@ REGEX_SOURCE_SYMBOL = re.compile(SOURCE_SYMBOL)
 REGEX_KCONFIG_DEF = re.compile(DEF)
 REGEX_KCONFIG_EXPR = re.compile(EXPR)
 REGEX_KCONFIG_STMT = re.compile(STMT)
-REGEX_KCONFIG_HELP = re.compile(r"^\s+(help|---help---)\s*$")
+REGEX_KCONFIG_HELP = re.compile(r"^\s+help\s*$")
 REGEX_FILTER_SYMBOLS = re.compile(r"[A-Za-z0-9]$")
 REGEX_NUMERIC = re.compile(r"0[xX][0-9a-fA-F]+|[0-9]+")
 REGEX_QUOTES = re.compile("(\"(.*?)\")")
index 2cbeae6..60d4a79 100755 (executable)
@@ -3045,11 +3045,7 @@ sub process {
 
                                if ($lines[$ln - 1] =~ /^\+\s*(?:bool|tristate|prompt)\s*["']/) {
                                        $is_start = 1;
-                               } elsif ($lines[$ln - 1] =~ /^\+\s*(?:help|---help---)\s*$/) {
-                                       if ($lines[$ln - 1] =~ "---help---") {
-                                               WARN("CONFIG_DESCRIPTION",
-                                                    "prefer 'help' over '---help---' for new help texts\n" . $herecurr);
-                                       }
+                               } elsif ($lines[$ln - 1] =~ /^\+\s*(?:---)?help(?:---)?$/) {
                                        $length = -1;
                                }
 
index b4fa0e4..2f9afff 100644 (file)
@@ -5,7 +5,7 @@
 
 #include "images.h"
 
-const char *xpm_load[] = {
+const char * const xpm_load[] = {
 "22 22 5 1",
 ". c None",
 "# c #000000",
@@ -35,7 +35,7 @@ const char *xpm_load[] = {
 "###############.......",
 "......................"};
 
-const char *xpm_save[] = {
+const char * const xpm_save[] = {
 "22 22 5 1",
 ". c None",
 "# c #000000",
@@ -65,7 +65,7 @@ const char *xpm_save[] = {
 "..##################..",
 "......................"};
 
-const char *xpm_back[] = {
+const char * const xpm_back[] = {
 "22 22 3 1",
 ". c None",
 "# c #000083",
@@ -93,7 +93,7 @@ const char *xpm_back[] = {
 "......................",
 "......................"};
 
-const char *xpm_tree_view[] = {
+const char * const xpm_tree_view[] = {
 "22 22 2 1",
 ". c None",
 "# c #000000",
@@ -120,7 +120,7 @@ const char *xpm_tree_view[] = {
 "......................",
 "......................"};
 
-const char *xpm_single_view[] = {
+const char * const xpm_single_view[] = {
 "22 22 2 1",
 ". c None",
 "# c #000000",
@@ -147,7 +147,7 @@ const char *xpm_single_view[] = {
 "......................",
 "......................"};
 
-const char *xpm_split_view[] = {
+const char * const xpm_split_view[] = {
 "22 22 2 1",
 ". c None",
 "# c #000000",
@@ -174,7 +174,7 @@ const char *xpm_split_view[] = {
 "......................",
 "......................"};
 
-const char *xpm_symbol_no[] = {
+const char * const xpm_symbol_no[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -191,7 +191,7 @@ const char *xpm_symbol_no[] = {
 " .......... ",
 "            "};
 
-const char *xpm_symbol_mod[] = {
+const char * const xpm_symbol_mod[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -208,7 +208,7 @@ const char *xpm_symbol_mod[] = {
 " .......... ",
 "            "};
 
-const char *xpm_symbol_yes[] = {
+const char * const xpm_symbol_yes[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -225,7 +225,7 @@ const char *xpm_symbol_yes[] = {
 " .......... ",
 "            "};
 
-const char *xpm_choice_no[] = {
+const char * const xpm_choice_no[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -242,7 +242,7 @@ const char *xpm_choice_no[] = {
 "    ....    ",
 "            "};
 
-const char *xpm_choice_yes[] = {
+const char * const xpm_choice_yes[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -259,7 +259,7 @@ const char *xpm_choice_yes[] = {
 "    ....    ",
 "            "};
 
-const char *xpm_menu[] = {
+const char * const xpm_menu[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -276,7 +276,7 @@ const char *xpm_menu[] = {
 " .......... ",
 "            "};
 
-const char *xpm_menu_inv[] = {
+const char * const xpm_menu_inv[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -293,7 +293,7 @@ const char *xpm_menu_inv[] = {
 " .......... ",
 "            "};
 
-const char *xpm_menuback[] = {
+const char * const xpm_menuback[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
@@ -310,7 +310,7 @@ const char *xpm_menuback[] = {
 " .......... ",
 "            "};
 
-const char *xpm_void[] = {
+const char * const xpm_void[] = {
 "12 12 2 1",
 "  c white",
 ". c black",
index d8ff614..7212dec 100644 (file)
 extern "C" {
 #endif
 
-extern const char *xpm_load[];
-extern const char *xpm_save[];
-extern const char *xpm_back[];
-extern const char *xpm_tree_view[];
-extern const char *xpm_single_view[];
-extern const char *xpm_split_view[];
-extern const char *xpm_symbol_no[];
-extern const char *xpm_symbol_mod[];
-extern const char *xpm_symbol_yes[];
-extern const char *xpm_choice_no[];
-extern const char *xpm_choice_yes[];
-extern const char *xpm_menu[];
-extern const char *xpm_menu_inv[];
-extern const char *xpm_menuback[];
-extern const char *xpm_void[];
+extern const char * const xpm_load[];
+extern const char * const xpm_save[];
+extern const char * const xpm_back[];
+extern const char * const xpm_tree_view[];
+extern const char * const xpm_single_view[];
+extern const char * const xpm_split_view[];
+extern const char * const xpm_symbol_no[];
+extern const char * const xpm_symbol_mod[];
+extern const char * const xpm_symbol_yes[];
+extern const char * const xpm_choice_no[];
+extern const char * const xpm_choice_yes[];
+extern const char * const xpm_menu[];
+extern const char * const xpm_menu_inv[];
+extern const char * const xpm_menuback[];
+extern const char * const xpm_void[];
 
 #ifdef __cplusplus
 }
index 6354c90..240109f 100644 (file)
@@ -36,7 +36,7 @@ struct buffer {
        YY_BUFFER_STATE state;
 };
 
-struct buffer *current_buf;
+static struct buffer *current_buf;
 
 static int last_ts, first_ts;
 
@@ -105,7 +105,7 @@ n   [A-Za-z0-9_-]
 "endchoice"            return T_ENDCHOICE;
 "endif"                        return T_ENDIF;
 "endmenu"              return T_ENDMENU;
-"help"|"---help---"    return T_HELP;
+"help"                 return T_HELP;
 "hex"                  return T_HEX;
 "if"                   return T_IF;
 "imply"                        return T_IMPLY;
index 23d1cb0..bc390df 100644 (file)
@@ -31,11 +31,6 @@ static ConfigSettings *configSettings;
 
 QAction *ConfigMainWindow::saveAction;
 
-static inline QString qgettext(const char* str)
-{
-       return QString::fromLocal8Bit(str);
-}
-
 ConfigSettings::ConfigSettings()
        : QSettings("kernel.org", "qconf")
 {
@@ -79,6 +74,13 @@ bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
        return true;
 }
 
+QIcon ConfigItem::symbolYesIcon;
+QIcon ConfigItem::symbolModIcon;
+QIcon ConfigItem::symbolNoIcon;
+QIcon ConfigItem::choiceYesIcon;
+QIcon ConfigItem::choiceNoIcon;
+QIcon ConfigItem::menuIcon;
+QIcon ConfigItem::menubackIcon;
 
 /*
  * set the new data
@@ -102,14 +104,14 @@ void ConfigItem::updateMenu(void)
 
        list = listView();
        if (goParent) {
-               setPixmap(promptColIdx, list->menuBackPix);
+               setIcon(promptColIdx, menubackIcon);
                prompt = "..";
                goto set_prompt;
        }
 
        sym = menu->sym;
        prop = menu->prompt;
-       prompt = qgettext(menu_get_prompt(menu));
+       prompt = menu_get_prompt(menu);
 
        if (prop) switch (prop->type) {
        case P_MENU:
@@ -119,15 +121,15 @@ void ConfigItem::updateMenu(void)
                         */
                        if (sym && list->rootEntry == menu)
                                break;
-                       setPixmap(promptColIdx, list->menuPix);
+                       setIcon(promptColIdx, menuIcon);
                } else {
                        if (sym)
                                break;
-                       setPixmap(promptColIdx, QIcon());
+                       setIcon(promptColIdx, QIcon());
                }
                goto set_prompt;
        case P_COMMENT:
-               setPixmap(promptColIdx, QIcon());
+               setIcon(promptColIdx, QIcon());
                goto set_prompt;
        default:
                ;
@@ -135,7 +137,7 @@ void ConfigItem::updateMenu(void)
        if (!sym)
                goto set_prompt;
 
-       setText(nameColIdx, QString::fromLocal8Bit(sym->name));
+       setText(nameColIdx, sym->name);
 
        type = sym_get_type(sym);
        switch (type) {
@@ -144,7 +146,7 @@ void ConfigItem::updateMenu(void)
                char ch;
 
                if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
-                       setPixmap(promptColIdx, QIcon());
+                       setIcon(promptColIdx, QIcon());
                        setText(noColIdx, QString());
                        setText(modColIdx, QString());
                        setText(yesColIdx, QString());
@@ -154,22 +156,22 @@ void ConfigItem::updateMenu(void)
                switch (expr) {
                case yes:
                        if (sym_is_choice_value(sym) && type == S_BOOLEAN)
-                               setPixmap(promptColIdx, list->choiceYesPix);
+                               setIcon(promptColIdx, choiceYesIcon);
                        else
-                               setPixmap(promptColIdx, list->symbolYesPix);
+                               setIcon(promptColIdx, symbolYesIcon);
                        setText(yesColIdx, "Y");
                        ch = 'Y';
                        break;
                case mod:
-                       setPixmap(promptColIdx, list->symbolModPix);
+                       setIcon(promptColIdx, symbolModIcon);
                        setText(modColIdx, "M");
                        ch = 'M';
                        break;
                default:
                        if (sym_is_choice_value(sym) && type == S_BOOLEAN)
-                               setPixmap(promptColIdx, list->choiceNoPix);
+                               setIcon(promptColIdx, choiceNoIcon);
                        else
-                               setPixmap(promptColIdx, list->symbolNoPix);
+                               setIcon(promptColIdx, symbolNoIcon);
                        setText(noColIdx, "N");
                        ch = 'N';
                        break;
@@ -265,7 +267,7 @@ void ConfigLineEdit::show(ConfigItem* i)
 {
        item = i;
        if (sym_get_string_value(item->menu->sym))
-               setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
+               setText(sym_get_string_value(item->menu->sym));
        else
                setText(QString());
        Parent::show();
@@ -280,7 +282,7 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
        case Qt::Key_Return:
        case Qt::Key_Enter:
                sym_set_string_value(item->menu->sym, text().toLatin1());
-               parent()->updateList(item);
+               parent()->updateList();
                break;
        default:
                Parent::keyPressEvent(e);
@@ -294,9 +296,6 @@ void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
 ConfigList::ConfigList(ConfigView* p, const char *name)
        : Parent(p),
          updateAll(false),
-         symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
-         choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
-         menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
          showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
          rootEntry(0), headerPopup(0)
 {
@@ -322,7 +321,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
                connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
        }
 
-       addColumn(promptColIdx);
+       showColumn(promptColIdx);
 
        reinit();
 }
@@ -340,21 +339,33 @@ bool ConfigList::menuSkip(struct menu *menu)
 
 void ConfigList::reinit(void)
 {
-       removeColumn(dataColIdx);
-       removeColumn(yesColIdx);
-       removeColumn(modColIdx);
-       removeColumn(noColIdx);
-       removeColumn(nameColIdx);
+       hideColumn(dataColIdx);
+       hideColumn(yesColIdx);
+       hideColumn(modColIdx);
+       hideColumn(noColIdx);
+       hideColumn(nameColIdx);
 
        if (showName)
-               addColumn(nameColIdx);
+               showColumn(nameColIdx);
        if (showRange) {
-               addColumn(noColIdx);
-               addColumn(modColIdx);
-               addColumn(yesColIdx);
+               showColumn(noColIdx);
+               showColumn(modColIdx);
+               showColumn(yesColIdx);
        }
        if (showData)
-               addColumn(dataColIdx);
+               showColumn(dataColIdx);
+
+       updateListAll();
+}
+
+void ConfigList::setOptionMode(QAction *action)
+{
+       if (action == showNormalAction)
+               optMode = normalOpt;
+       else if (action == showAllAction)
+               optMode = allOpt;
+       else
+               optMode = promptOpt;
 
        updateListAll();
 }
@@ -404,15 +415,15 @@ void ConfigList::updateSelection(void)
                emit menuSelected(menu);
 }
 
-void ConfigList::updateList(ConfigItem* item)
+void ConfigList::updateList()
 {
        ConfigItem* last = 0;
+       ConfigItem *item;
 
        if (!rootEntry) {
                if (mode != listMode)
                        goto update;
                QTreeWidgetItemIterator it(this);
-               ConfigItem* item;
 
                while (*it) {
                        item = (ConfigItem*)(*it);
@@ -446,7 +457,7 @@ void ConfigList::updateList(ConfigItem* item)
                return;
        }
 update:
-       updateMenuList(this, rootEntry);
+       updateMenuList(rootEntry);
        update();
        resizeColumnToContents(0);
 }
@@ -471,7 +482,7 @@ void ConfigList::setValue(ConfigItem* item, tristate val)
                        return;
                if (oldval == no && item->menu->list)
                        item->setExpanded(true);
-               parent()->updateList(item);
+               parent()->updateList();
                break;
        }
 }
@@ -505,7 +516,7 @@ void ConfigList::changeValue(ConfigItem* item)
                                item->setExpanded(true);
                }
                if (oldexpr != newexpr)
-                       parent()->updateList(item);
+                       parent()->updateList();
                break;
        case S_INT:
        case S_HEX:
@@ -524,7 +535,7 @@ void ConfigList::setRootMenu(struct menu *menu)
        type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
        if (type != P_MENU)
                return;
-       updateMenuList(this, 0);
+       updateMenuList(0);
        rootEntry = menu;
        updateListAll();
        if (currentItem()) {
@@ -628,7 +639,7 @@ hide:
        }
 }
 
-void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
+void ConfigList::updateMenuList(struct menu *menu)
 {
        struct menu* child;
        ConfigItem* item;
@@ -637,19 +648,19 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
        enum prop_type type;
 
        if (!menu) {
-               while (parent->topLevelItemCount() > 0)
+               while (topLevelItemCount() > 0)
                {
-                       delete parent->takeTopLevelItem(0);
+                       delete takeTopLevelItem(0);
                }
 
                return;
        }
 
-       last = (ConfigItem*)parent->topLevelItem(0);
+       last = (ConfigItem *)topLevelItem(0);
        if (last && !last->goParent)
                last = 0;
        for (child = menu->list; child; child = child->next) {
-               item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
+               item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
                type = child->prompt ? child->prompt->type : P_UNKNOWN;
 
                switch (mode) {
@@ -670,7 +681,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
                        if (!child->sym && !child->list && !child->prompt)
                                continue;
                        if (!item || item->menu != child)
-                               item = new ConfigItem(parent, last, child, visible);
+                               item = new ConfigItem(this, last, child, visible);
                        else
                                item->testUpdateMenu(visible);
 
@@ -683,7 +694,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
                }
 hide:
                if (item && item->menu == child) {
-                       last = (ConfigItem*)parent->topLevelItem(0);
+                       last = (ConfigItem *)topLevelItem(0);
                        if (last == item)
                                last = 0;
                        else while (last->nextSibling() != item)
@@ -774,7 +785,7 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e)
        idx = header()->logicalIndexAt(x);
        switch (idx) {
        case promptColIdx:
-               icon = item->pixmap(promptColIdx);
+               icon = item->icon(promptColIdx);
                if (!icon.isNull()) {
                        int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
                        if (x >= off && x < off + icon.availableSizes().first().width()) {
@@ -785,7 +796,8 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e)
                                        break;
                                ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
                                if (ptype == P_MENU && rootEntry != menu &&
-                                   mode != fullMode && mode != menuMode)
+                                   mode != fullMode && mode != menuMode &&
+                                    mode != listMode)
                                        emit menuSelected(menu);
                                else
                                        changeValue(item);
@@ -835,7 +847,7 @@ void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
        if (!menu)
                goto skip;
        ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
-       if (ptype == P_MENU) {
+       if (ptype == P_MENU && mode != listMode) {
                if (mode == singleMode)
                        emit itemSelected(menu);
                else if (mode == symbolMode)
@@ -864,46 +876,46 @@ void ConfigList::focusInEvent(QFocusEvent *e)
 
 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
 {
-       if (e->y() <= header()->geometry().bottom()) {
-               if (!headerPopup) {
-                       QAction *action;
-
-                       headerPopup = new QMenu(this);
-                       action = new QAction("Show Name", this);
-                         action->setCheckable(true);
-                         connect(action, SIGNAL(toggled(bool)),
-                                 parent(), SLOT(setShowName(bool)));
-                         connect(parent(), SIGNAL(showNameChanged(bool)),
-                                 action, SLOT(setOn(bool)));
-                         action->setChecked(showName);
-                         headerPopup->addAction(action);
-                       action = new QAction("Show Range", this);
-                         action->setCheckable(true);
-                         connect(action, SIGNAL(toggled(bool)),
-                                 parent(), SLOT(setShowRange(bool)));
-                         connect(parent(), SIGNAL(showRangeChanged(bool)),
-                                 action, SLOT(setOn(bool)));
-                         action->setChecked(showRange);
-                         headerPopup->addAction(action);
-                       action = new QAction("Show Data", this);
-                         action->setCheckable(true);
-                         connect(action, SIGNAL(toggled(bool)),
-                                 parent(), SLOT(setShowData(bool)));
-                         connect(parent(), SIGNAL(showDataChanged(bool)),
-                                 action, SLOT(setOn(bool)));
-                         action->setChecked(showData);
-                         headerPopup->addAction(action);
-               }
-               headerPopup->exec(e->globalPos());
-               e->accept();
-       } else
-               e->ignore();
+       if (!headerPopup) {
+               QAction *action;
+
+               headerPopup = new QMenu(this);
+               action = new QAction("Show Name", this);
+               action->setCheckable(true);
+               connect(action, SIGNAL(toggled(bool)),
+                       parent(), SLOT(setShowName(bool)));
+               connect(parent(), SIGNAL(showNameChanged(bool)),
+                       action, SLOT(setOn(bool)));
+               action->setChecked(showName);
+               headerPopup->addAction(action);
+
+               action = new QAction("Show Range", this);
+               action->setCheckable(true);
+               connect(action, SIGNAL(toggled(bool)),
+                       parent(), SLOT(setShowRange(bool)));
+               connect(parent(), SIGNAL(showRangeChanged(bool)),
+                       action, SLOT(setOn(bool)));
+               action->setChecked(showRange);
+               headerPopup->addAction(action);
+
+               action = new QAction("Show Data", this);
+               action->setCheckable(true);
+               connect(action, SIGNAL(toggled(bool)),
+                       parent(), SLOT(setShowData(bool)));
+               connect(parent(), SIGNAL(showDataChanged(bool)),
+                       action, SLOT(setOn(bool)));
+               action->setChecked(showData);
+               headerPopup->addAction(action);
+       }
+
+       headerPopup->exec(e->globalPos());
+       e->accept();
 }
 
 ConfigView*ConfigView::viewList;
-QAction *ConfigView::showNormalAction;
-QAction *ConfigView::showAllAction;
-QAction *ConfigView::showPromptAction;
+QAction *ConfigList::showNormalAction;
+QAction *ConfigList::showAllAction;
+QAction *ConfigList::showPromptAction;
 
 ConfigView::ConfigView(QWidget* parent, const char *name)
        : Parent(parent)
@@ -934,18 +946,6 @@ ConfigView::~ConfigView(void)
        }
 }
 
-void ConfigView::setOptionMode(QAction *act)
-{
-       if (act == showNormalAction)
-               list->optMode = normalOpt;
-       else if (act == showAllAction)
-               list->optMode = allOpt;
-       else
-               list->optMode = promptOpt;
-
-       list->updateListAll();
-}
-
 void ConfigView::setShowName(bool b)
 {
        if (list->showName != b) {
@@ -984,12 +984,12 @@ void ConfigList::setAllOpen(bool open)
        }
 }
 
-void ConfigView::updateList(ConfigItem* item)
+void ConfigView::updateList()
 {
        ConfigView* v;
 
        for (v = viewList; v; v = v->nextView)
-               v->list->updateList(item);
+               v->list->updateList();
 }
 
 void ConfigView::updateListAll(void)
@@ -1287,16 +1287,17 @@ void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
        Parent::contextMenuEvent(e);
 }
 
-ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
+ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
        : Parent(parent), result(NULL)
 {
-       setObjectName(name);
+       setObjectName("search");
        setWindowTitle("Search Config");
 
        QVBoxLayout* layout1 = new QVBoxLayout(this);
        layout1->setContentsMargins(11, 11, 11, 11);
        layout1->setSpacing(6);
-       QHBoxLayout* layout2 = new QHBoxLayout(0);
+
+       QHBoxLayout* layout2 = new QHBoxLayout();
        layout2->setContentsMargins(0, 0, 0, 0);
        layout2->setSpacing(6);
        layout2->addWidget(new QLabel("Find:", this));
@@ -1311,9 +1312,9 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
 
        split = new QSplitter(this);
        split->setOrientation(Qt::Vertical);
-       list = new ConfigView(split, name);
+       list = new ConfigView(split, "search");
        list->list->mode = listMode;
-       info = new ConfigInfoView(split, name);
+       info = new ConfigInfoView(split, "search");
        connect(list->list, SIGNAL(menuChanged(struct menu *)),
                info, SLOT(setInfo(struct menu *)));
        connect(list->list, SIGNAL(menuChanged(struct menu *)),
@@ -1321,25 +1322,23 @@ ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *nam
 
        layout1->addWidget(split);
 
-       if (name) {
-               QVariant x, y;
-               int width, height;
-               bool ok;
+       QVariant x, y;
+       int width, height;
+       bool ok;
 
-               configSettings->beginGroup(name);
-               width = configSettings->value("/window width", parent->width() / 2).toInt();
-               height = configSettings->value("/window height", parent->height() / 2).toInt();
-               resize(width, height);
-               x = configSettings->value("/window x");
-               y = configSettings->value("/window y");
-               if ((x.isValid())&&(y.isValid()))
-                       move(x.toInt(), y.toInt());
-               QList<int> sizes = configSettings->readSizes("/split", &ok);
-               if (ok)
-                       split->setSizes(sizes);
-               configSettings->endGroup();
-               connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
-       }
+       configSettings->beginGroup("search");
+       width = configSettings->value("/window width", parent->width() / 2).toInt();
+       height = configSettings->value("/window height", parent->height() / 2).toInt();
+       resize(width, height);
+       x = configSettings->value("/window x");
+       y = configSettings->value("/window y");
+       if (x.isValid() && y.isValid())
+               move(x.toInt(), y.toInt());
+       QList<int> sizes = configSettings->readSizes("/split", &ok);
+       if (ok)
+               split->setSizes(sizes);
+       configSettings->endGroup();
+       connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
 }
 
 void ConfigSearchWindow::saveSettings(void)
@@ -1381,7 +1380,6 @@ void ConfigSearchWindow::search(void)
 ConfigMainWindow::ConfigMainWindow(void)
        : searchWindow(0)
 {
-       QMenuBar* menu;
        bool ok = true;
        QVariant x, y;
        int width, height;
@@ -1402,6 +1400,15 @@ ConfigMainWindow::ConfigMainWindow(void)
        if ((x.isValid())&&(y.isValid()))
                move(x.toInt(), y.toInt());
 
+       // set up icons
+       ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
+       ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
+       ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
+       ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
+       ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
+       ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
+       ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
+
        QWidget *widget = new QWidget(this);
        QVBoxLayout *layout = new QVBoxLayout(widget);
        setCentralWidget(widget);
@@ -1432,10 +1439,6 @@ ConfigMainWindow::ConfigMainWindow(void)
        setTabOrder(configList, helpText);
        configList->setFocus();
 
-       menu = menuBar();
-       toolBar = new QToolBar("Tools", this);
-       addToolBar(toolBar);
-
        backAction = new QAction(QPixmap(xpm_back), "Back", this);
        connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
 
@@ -1485,17 +1488,17 @@ ConfigMainWindow::ConfigMainWindow(void)
 
        QActionGroup *optGroup = new QActionGroup(this);
        optGroup->setExclusive(true);
-       connect(optGroup, SIGNAL(triggered(QAction*)), configView,
+       connect(optGroup, SIGNAL(triggered(QAction*)), configList,
                SLOT(setOptionMode(QAction *)));
-       connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
+       connect(optGroup, SIGNAL(triggered(QAction *)), menuList,
                SLOT(setOptionMode(QAction *)));
 
-       configView->showNormalAction = new QAction("Show Normal Options", optGroup);
-       configView->showAllAction = new QAction("Show All Options", optGroup);
-       configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
-       configView->showNormalAction->setCheckable(true);
-       configView->showAllAction->setCheckable(true);
-       configView->showPromptAction->setCheckable(true);
+       ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
+       ConfigList::showNormalAction->setCheckable(true);
+       ConfigList::showAllAction = new QAction("Show All Options", optGroup);
+       ConfigList::showAllAction->setCheckable(true);
+       ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
+       ConfigList::showPromptAction->setCheckable(true);
 
        QAction *showDebugAction = new QAction("Show Debug Info", this);
          showDebugAction->setCheckable(true);
@@ -1508,6 +1511,7 @@ ConfigMainWindow::ConfigMainWindow(void)
          connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
 
        // init tool bar
+       QToolBar *toolBar = addToolBar("Tools");
        toolBar->addAction(backAction);
        toolBar->addSeparator();
        toolBar->addAction(loadAction);
@@ -1517,33 +1521,32 @@ ConfigMainWindow::ConfigMainWindow(void)
        toolBar->addAction(splitViewAction);
        toolBar->addAction(fullViewAction);
 
-       // create config menu
-       QMenu* config = menu->addMenu("&File");
-       config->addAction(loadAction);
-       config->addAction(saveAction);
-       config->addAction(saveAsAction);
-       config->addSeparator();
-       config->addAction(quitAction);
+       // create file menu
+       QMenu *menu = menuBar()->addMenu("&File");
+       menu->addAction(loadAction);
+       menu->addAction(saveAction);
+       menu->addAction(saveAsAction);
+       menu->addSeparator();
+       menu->addAction(quitAction);
 
        // create edit menu
-       QMenu* editMenu = menu->addMenu("&Edit");
-       editMenu->addAction(searchAction);
+       menu = menuBar()->addMenu("&Edit");
+       menu->addAction(searchAction);
 
        // create options menu
-       QMenu* optionMenu = menu->addMenu("&Option");
-       optionMenu->addAction(showNameAction);
-       optionMenu->addAction(showRangeAction);
-       optionMenu->addAction(showDataAction);
-       optionMenu->addSeparator();
-       optionMenu->addActions(optGroup->actions());
-       optionMenu->addSeparator();
-       optionMenu->addAction(showDebugAction);
+       menu = menuBar()->addMenu("&Option");
+       menu->addAction(showNameAction);
+       menu->addAction(showRangeAction);
+       menu->addAction(showDataAction);
+       menu->addSeparator();
+       menu->addActions(optGroup->actions());
+       menu->addSeparator();
+       menu->addAction(showDebugAction);
 
        // create help menu
-       menu->addSeparator();
-       QMenu* helpMenu = menu->addMenu("&Help");
-       helpMenu->addAction(showIntroAction);
-       helpMenu->addAction(showAboutAction);
+       menu = menuBar()->addMenu("&Help");
+       menu->addAction(showIntroAction);
+       menu->addAction(showAboutAction);
 
        connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
                 helpText, SLOT (clicked (const QUrl &)) );
@@ -1646,7 +1649,7 @@ void ConfigMainWindow::saveConfigAs(void)
 void ConfigMainWindow::searchConfig(void)
 {
        if (!searchWindow)
-               searchWindow = new ConfigSearchWindow(this, "search");
+               searchWindow = new ConfigSearchWindow(this);
        searchWindow->show();
 }
 
index 5eeab4a..461df64 100644 (file)
@@ -69,11 +69,13 @@ protected:
 public slots:
        void setRootMenu(struct menu *menu);
 
-       void updateList(ConfigItem *item);
+       void updateList();
        void setValue(ConfigItem* item, tristate val);
        void changeValue(ConfigItem* item);
        void updateSelection(void);
        void saveSettings(void);
+       void setOptionMode(QAction *action);
+
 signals:
        void menuChanged(struct menu *menu);
        void menuSelected(struct menu *menu);
@@ -85,35 +87,19 @@ public:
        void updateListAll(void)
        {
                updateAll = true;
-               updateList(NULL);
+               updateList();
                updateAll = false;
        }
-       ConfigList* listView()
-       {
-               return this;
-       }
-       void addColumn(colIdx idx)
-       {
-               showColumn(idx);
-       }
-       void removeColumn(colIdx idx)
-       {
-               hideColumn(idx);
-       }
        void setAllOpen(bool open);
        void setParentMenu(void);
 
        bool menuSkip(struct menu *);
 
        void updateMenuList(ConfigItem *parent, struct menu*);
-       void updateMenuList(ConfigList *parent, struct menu*);
+       void updateMenuList(struct menu *menu);
 
        bool updateAll;
 
-       QPixmap symbolYesPix, symbolModPix, symbolNoPix;
-       QPixmap choiceYesPix, choiceNoPix;
-       QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
-
        bool showName, showRange, showData;
        enum listMode mode;
        enum optionMode optMode;
@@ -121,6 +107,8 @@ public:
        QPalette disabledColorGroup;
        QPalette inactivedColorGroup;
        QMenu* headerPopup;
+
+       static QAction *showNormalAction, *showAllAction, *showPromptAction;
 };
 
 class ConfigItem : public QTreeWidgetItem {
@@ -168,28 +156,16 @@ public:
 
                return ret;
        }
-       void setText(colIdx idx, const QString& text)
-       {
-               Parent::setText(idx, text);
-       }
-       QString text(colIdx idx) const
-       {
-               return Parent::text(idx);
-       }
-       void setPixmap(colIdx idx, const QIcon &icon)
-       {
-               Parent::setIcon(idx, icon);
-       }
-       const QIcon pixmap(colIdx idx) const
-       {
-               return icon(idx);
-       }
        // TODO: Implement paintCell
 
        ConfigItem* nextItem;
        struct menu *menu;
        bool visible;
        bool goParent;
+
+       static QIcon symbolYesIcon, symbolModIcon, symbolNoIcon;
+       static QIcon choiceYesIcon, choiceNoIcon;
+       static QIcon menuIcon, menubackIcon;
 };
 
 class ConfigLineEdit : public QLineEdit {
@@ -214,7 +190,7 @@ class ConfigView : public QWidget {
 public:
        ConfigView(QWidget* parent, const char *name = 0);
        ~ConfigView(void);
-       static void updateList(ConfigItem* item);
+       static void updateList();
        static void updateListAll(void);
 
        bool showName(void) const { return list->showName; }
@@ -224,7 +200,6 @@ public slots:
        void setShowName(bool);
        void setShowRange(bool);
        void setShowData(bool);
-       void setOptionMode(QAction *);
 signals:
        void showNameChanged(bool);
        void showRangeChanged(bool);
@@ -235,10 +210,6 @@ public:
 
        static ConfigView* viewList;
        ConfigView* nextView;
-
-       static QAction *showNormalAction;
-       static QAction *showAllAction;
-       static QAction *showPromptAction;
 };
 
 class ConfigInfoView : public QTextBrowser {
@@ -276,7 +247,7 @@ class ConfigSearchWindow : public QDialog {
        Q_OBJECT
        typedef class QDialog Parent;
 public:
-       ConfigSearchWindow(ConfigMainWindow* parent, const char *name = 0);
+       ConfigSearchWindow(ConfigMainWindow *parent);
 
 public slots:
        void saveSettings(void);
@@ -326,7 +297,6 @@ protected:
        ConfigView *configView;
        ConfigList *configList;
        ConfigInfoView *helpText;
-       QToolBar *toolBar;
        QAction *backAction;
        QAction *singleViewAction;
        QAction *splitViewAction;
index 9363e37..ffa3ec6 100644 (file)
@@ -15,15 +15,21 @@ struct symbol symbol_yes = {
        .name = "y",
        .curr = { "y", yes },
        .flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_mod = {
+};
+
+struct symbol symbol_mod = {
        .name = "m",
        .curr = { "m", mod },
        .flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_no = {
+};
+
+struct symbol symbol_no = {
        .name = "n",
        .curr = { "n", no },
        .flags = SYMBOL_CONST|SYMBOL_VALID,
-}, symbol_empty = {
+};
+
+static struct symbol symbol_empty = {
        .name = "",
        .curr = { "", no },
        .flags = SYMBOL_VALID,
@@ -31,7 +37,7 @@ struct symbol symbol_yes = {
 
 struct symbol *sym_defconfig_list;
 struct symbol *modules_sym;
-tristate modules_val;
+static tristate modules_val;
 
 enum symbol_type sym_get_type(struct symbol *sym)
 {
index 6aeb99a..a20b2bb 100644 (file)
@@ -1950,8 +1950,7 @@ static int snd_echo_create(struct snd_card *card,
                snd_echo_free(chip);
                return -EBUSY;
        }
-       chip->dsp_registers = (volatile u32 __iomem *)
-               ioremap(chip->dsp_registers_phys, sz);
+       chip->dsp_registers = ioremap(chip->dsp_registers_phys, sz);
        if (!chip->dsp_registers) {
                dev_err(chip->card->dev, "ioremap failed\n");
                snd_echo_free(chip);
@@ -2213,7 +2212,6 @@ static int snd_echo_resume(struct device *dev)
        if (err < 0) {
                kfree(commpage_bak);
                dev_err(dev, "resume init_hw err=%d\n", err);
-               snd_echo_free(chip);
                return err;
        }
 
@@ -2240,7 +2238,6 @@ static int snd_echo_resume(struct device *dev)
        if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
                        KBUILD_MODNAME, chip)) {
                dev_err(chip->card->dev, "cannot grab irq\n");
-               snd_echo_free(chip);
                return -EBUSY;
        }
        chip->irq = pci->irq;
index 30c6409..0afe13f 100644 (file)
@@ -419,7 +419,7 @@ struct echoaudio {
        short asic_code;                /* Current ASIC code */
        u32 comm_page_phys;                     /* Physical address of the
                                                 * memory seen by DSP */
-       volatile u32 __iomem *dsp_registers;    /* DSP's register base */
+       u32 __iomem *dsp_registers;             /* DSP's register base */
        u32 active_mask;                        /* Chs. active mask or
                                                 * punks out */
 #ifdef CONFIG_PM_SLEEP
index 4bbd12d..b8c8490 100644 (file)
@@ -1863,6 +1863,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
 }
 
 static const struct snd_pci_quirk force_connect_list[] = {
+       SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1),
        SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1),
        {}
 };
index 2477f3e..7f9d352 100644 (file)
@@ -4125,7 +4125,7 @@ static int micmute_led_set(struct led_classdev *led_cdev,
        struct alc_spec *spec = codec->spec;
 
        alc_update_gpio_led(codec, spec->gpio_mic_led_mask,
-                           spec->micmute_led_polarity, !!brightness);
+                           spec->micmute_led_polarity, !brightness);
        return 0;
 }
 
@@ -4160,10 +4160,6 @@ static void alc269_fixup_hp_gpio_led(struct hda_codec *codec,
 static void alc285_fixup_hp_gpio_led(struct hda_codec *codec,
                                const struct hda_fixup *fix, int action)
 {
-       struct alc_spec *spec = codec->spec;
-
-       spec->micmute_led_polarity = 1;
-
        alc_fixup_hp_gpio_led(codec, action, 0x04, 0x01);
 }
 
@@ -6159,6 +6155,7 @@ enum {
        ALC269_FIXUP_CZC_L101,
        ALC269_FIXUP_LEMOTE_A1802,
        ALC269_FIXUP_LEMOTE_A190X,
+       ALC256_FIXUP_INTEL_NUC8_RUGGED,
 };
 
 static const struct hda_fixup alc269_fixups[] = {
@@ -7480,6 +7477,15 @@ static const struct hda_fixup alc269_fixups[] = {
                },
                .chain_id = ALC269_FIXUP_DMIC,
        },
+       [ALC256_FIXUP_INTEL_NUC8_RUGGED] = {
+               .type = HDA_FIXUP_PINS,
+               .v.pins = (const struct hda_pintbl[]) {
+                       { 0x1b, 0x01a1913c }, /* use as headset mic, without its own jack detect */
+                       { }
+               },
+               .chained = true,
+               .chain_id = ALC269_FIXUP_HEADSET_MODE
+       },
 };
 
 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
@@ -7777,6 +7783,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
        SND_PCI_QUIRK(0x10ec, 0x118c, "Medion EE4254 MD62100", ALC256_FIXUP_MEDION_HEADSET_NO_PRESENCE),
        SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
        SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
+       SND_PCI_QUIRK(0x8086, 0x2080, "Intel NUC 8 Rugged", ALC256_FIXUP_INTEL_NUC8_RUGGED),
 
 #if 0
        /* Below is a quirk table taken from the old code.
index de43267..5351d71 100644 (file)
@@ -137,6 +137,7 @@ struct snd_usb_substream {
        unsigned int tx_length_quirk:1; /* add length specifier to transfers */
        unsigned int fmt_type;          /* USB audio format type (1-3) */
        unsigned int pkt_offset_adj;    /* Bytes to drop from beginning of packets (for non-compliant devices) */
+       unsigned int stream_offset_adj; /* Bytes to drop from beginning of stream (for non-compliant devices) */
 
        unsigned int running: 1;        /* running status */
 
index c369c81..5b43e9e 100644 (file)
@@ -371,6 +371,7 @@ static const struct usbmix_name_map asus_rog_map[] = {
 };
 
 static const struct usbmix_name_map lenovo_p620_rear_map[] = {
+       { 19, NULL, 2 }, /* FU, Volume */
        { 19, NULL, 12 }, /* FU, Input Gain Pad */
        {}
 };
index cec1cfd..199cdbf 100644 (file)
@@ -185,6 +185,7 @@ static const struct rc_config {
        { USB_ID(0x041e, 0x3042), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 */
        { USB_ID(0x041e, 0x30df), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 Pro */
        { USB_ID(0x041e, 0x3237), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 Pro */
+       { USB_ID(0x041e, 0x3263), 0, 1, 1, 1,  1,  0x000d }, /* Usb X-Fi S51 Pro */
        { USB_ID(0x041e, 0x3048), 2, 2, 6, 6,  2,  0x6e91 }, /* Toshiba SB0500 */
 };
 
index 986145f..a4d4d71 100644 (file)
@@ -329,7 +329,7 @@ static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
                elem->cached |= 1;
                elem->cache_val[0] = val;
        } else {
-               usb_audio_dbg(chip, "Failed to set buss param, err:%d\n", err);
+               usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
        }
 
        return err > 0 ? 1 : 0;
index 415bfec..5600751 100644 (file)
@@ -1420,6 +1420,12 @@ static void retire_capture_urb(struct snd_usb_substream *subs,
                        // continue;
                }
                bytes = urb->iso_frame_desc[i].actual_length;
+               if (subs->stream_offset_adj > 0) {
+                       unsigned int adj = min(subs->stream_offset_adj, bytes);
+                       cp += adj;
+                       bytes -= adj;
+                       subs->stream_offset_adj -= adj;
+               }
                frames = bytes / stride;
                if (!subs->txfr_quirk)
                        bytes = frames * stride;
index adb3b62..d79e3dd 100644 (file)
@@ -3558,6 +3558,62 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
                }
        }
 },
+{
+       /*
+        * PIONEER DJ DDJ-RB
+        * PCM is 4 channels out, 2 dummy channels in @ 44.1 fixed
+        * The feedback for the output is the dummy input.
+        */
+       USB_DEVICE_VENDOR_SPEC(0x2b73, 0x000e),
+       .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
+               .ifnum = QUIRK_ANY_INTERFACE,
+               .type = QUIRK_COMPOSITE,
+               .data = (const struct snd_usb_audio_quirk[]) {
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = &(const struct audioformat) {
+                                       .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+                                       .channels = 4,
+                                       .iface = 0,
+                                       .altsetting = 1,
+                                       .altset_idx = 1,
+                                       .endpoint = 0x01,
+                                       .ep_attr = USB_ENDPOINT_XFER_ISOC|
+                                                  USB_ENDPOINT_SYNC_ASYNC,
+                                       .rates = SNDRV_PCM_RATE_44100,
+                                       .rate_min = 44100,
+                                       .rate_max = 44100,
+                                       .nr_rates = 1,
+                                       .rate_table = (unsigned int[]) { 44100 }
+                               }
+                       },
+                       {
+                               .ifnum = 0,
+                               .type = QUIRK_AUDIO_FIXED_ENDPOINT,
+                               .data = &(const struct audioformat) {
+                                       .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+                                       .channels = 2,
+                                       .iface = 0,
+                                       .altsetting = 1,
+                                       .altset_idx = 1,
+                                       .endpoint = 0x82,
+                                       .ep_attr = USB_ENDPOINT_XFER_ISOC|
+                                                USB_ENDPOINT_SYNC_ASYNC|
+                                                USB_ENDPOINT_USAGE_IMPLICIT_FB,
+                                       .rates = SNDRV_PCM_RATE_44100,
+                                       .rate_min = 44100,
+                                       .rate_max = 44100,
+                                       .nr_rates = 1,
+                                       .rate_table = (unsigned int[]) { 44100 }
+                               }
+                       },
+                       {
+                               .ifnum = -1
+                       }
+               }
+       }
+},
 
 #define ALC1220_VB_DESKTOP(vend, prod) { \
        USB_DEVICE(vend, prod), \
@@ -3662,7 +3718,13 @@ ALC1220_VB_DESKTOP(0x26ce, 0x0a01), /* Asrock TRX40 Creator */
  * with.
  */
 {
-       USB_DEVICE(0x534d, 0x2109),
+       .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
+                      USB_DEVICE_ID_MATCH_INT_CLASS |
+                      USB_DEVICE_ID_MATCH_INT_SUBCLASS,
+       .idVendor = 0x534d,
+       .idProduct = 0x2109,
+       .bInterfaceClass = USB_CLASS_AUDIO,
+       .bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
        .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
                .vendor_name = "MacroSilicon",
                .product_name = "MS2109",
index c551141..abf99b8 100644 (file)
@@ -1495,6 +1495,9 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
        case USB_ID(0x2b73, 0x000a): /* Pioneer DJ DJM-900NXS2 */
                pioneer_djm_set_format_quirk(subs);
                break;
+       case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
+               subs->stream_offset_adj = 2;
+               break;
        }
 }
 
index 4d1e657..ca76ba5 100644 (file)
@@ -94,6 +94,7 @@ static void snd_usb_init_substream(struct snd_usb_stream *as,
        subs->tx_length_quirk = as->chip->tx_length_quirk;
        subs->speed = snd_usb_get_speed(subs->dev);
        subs->pkt_offset_adj = 0;
+       subs->stream_offset_adj = 0;
 
        snd_usb_set_pcm_ops(as->pcm, stream);
 
index 436ec76..7a6b148 100644 (file)
@@ -231,11 +231,13 @@ struct kvm_guest_debug_arch {
 #define KVM_SYNC_GSCB   (1UL << 9)
 #define KVM_SYNC_BPBC   (1UL << 10)
 #define KVM_SYNC_ETOKEN (1UL << 11)
+#define KVM_SYNC_DIAG318 (1UL << 12)
 
 #define KVM_SYNC_S390_VALID_FIELDS \
        (KVM_SYNC_PREFIX | KVM_SYNC_GPRS | KVM_SYNC_ACRS | KVM_SYNC_CRS | \
         KVM_SYNC_ARCH0 | KVM_SYNC_PFAULT | KVM_SYNC_VRS | KVM_SYNC_RICCB | \
-        KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN)
+        KVM_SYNC_FPRS | KVM_SYNC_GSCB | KVM_SYNC_BPBC | KVM_SYNC_ETOKEN | \
+        KVM_SYNC_DIAG318)
 
 /* length and alignment of the sdnx as a power of two */
 #define SDNXC 8
@@ -264,7 +266,8 @@ struct kvm_sync_regs {
        __u8 reserved2 : 7;
        __u8 padding1[51];      /* riccb needs to be 64byte aligned */
        __u8 riccb[64];         /* runtime instrumentation controls block */
-       __u8 padding2[192];     /* sdnx needs to be 256byte aligned */
+       __u64 diag318;          /* diagnose 0x318 info */
+       __u8 padding2[184];     /* sdnx needs to be 256byte aligned */
        union {
                __u8 sdnx[SDNXL];  /* state description annex */
                struct {
index ede162f..0e93107 100644 (file)
@@ -67,7 +67,7 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,
        if (!info->btf_id || !info->nr_func_info ||
            btf__get_from_id(info->btf_id, &prog_btf))
                goto print;
-       finfo = (struct bpf_func_info *)info->func_info;
+       finfo = u64_to_ptr(info->func_info);
        func_type = btf__type_by_id(prog_btf, finfo->type_id);
        if (!func_type || !btf_is_func(func_type))
                goto print;
index 8a4c2b3..f611846 100644 (file)
@@ -143,6 +143,20 @@ static int codegen_datasec_def(struct bpf_object *obj,
                              var_name, align);
                        return -EINVAL;
                }
+               /* Assume 32-bit architectures when generating data section
+                * struct memory layout. Given bpftool can't know which target
+                * host architecture it's emitting skeleton for, we need to be
+                * conservative and assume 32-bit one to ensure enough padding
+                * bytes are generated for pointer and long types. This will
+                * still work correctly for 64-bit architectures, because in
+                * the worst case we'll generate unnecessary padding field,
+                * which on 64-bit architectures is not strictly necessary and
+                * would be handled by natural 8-byte alignment. But it still
+                * will be a correct memory layout, based on recorded offsets
+                * in BTF.
+                */
+               if (align > 4)
+                       align = 4;
 
                align_off = (off + align - 1) / align * align;
                if (align_off != need_off) {
@@ -397,7 +411,7 @@ static int do_skeleton(int argc, char **argv)
                {                                                           \n\
                        struct %1$s *obj;                                   \n\
                                                                            \n\
-                       obj = (typeof(obj))calloc(1, sizeof(*obj));         \n\
+                       obj = (struct %1$s *)calloc(1, sizeof(*obj));       \n\
                        if (!obj)                                           \n\
                                return NULL;                                \n\
                        if (%1$s__create_skeleton(obj))                     \n\
@@ -461,7 +475,7 @@ static int do_skeleton(int argc, char **argv)
                {                                                           \n\
                        struct bpf_object_skeleton *s;                      \n\
                                                                            \n\
-                       s = (typeof(s))calloc(1, sizeof(*s));               \n\
+                       s = (struct bpf_object_skeleton *)calloc(1, sizeof(*s));\n\
                        if (!s)                                             \n\
                                return -1;                                  \n\
                        obj->skeleton = s;                                  \n\
@@ -479,7 +493,7 @@ static int do_skeleton(int argc, char **argv)
                                /* maps */                                  \n\
                                s->map_cnt = %zu;                           \n\
                                s->map_skel_sz = sizeof(*s->maps);          \n\
-                               s->maps = (typeof(s->maps))calloc(s->map_cnt, s->map_skel_sz);\n\
+                               s->maps = (struct bpf_map_skeleton *)calloc(s->map_cnt, s->map_skel_sz);\n\
                                if (!s->maps)                               \n\
                                        goto err;                           \n\
                        ",
@@ -515,7 +529,7 @@ static int do_skeleton(int argc, char **argv)
                                /* programs */                              \n\
                                s->prog_cnt = %zu;                          \n\
                                s->prog_skel_sz = sizeof(*s->progs);        \n\
-                               s->progs = (typeof(s->progs))calloc(s->prog_cnt, s->prog_skel_sz);\n\
+                               s->progs = (struct bpf_prog_skeleton *)calloc(s->prog_cnt, s->prog_skel_sz);\n\
                                if (!s->progs)                              \n\
                                        goto err;                           \n\
                        ",
index 1b79375..a89f09e 100644 (file)
@@ -106,7 +106,7 @@ static int show_link_close_json(int fd, struct bpf_link_info *info)
        switch (info->type) {
        case BPF_LINK_TYPE_RAW_TRACEPOINT:
                jsonw_string_field(json_wtr, "tp_name",
-                                  (const char *)info->raw_tracepoint.tp_name);
+                                  u64_to_ptr(info->raw_tracepoint.tp_name));
                break;
        case BPF_LINK_TYPE_TRACING:
                err = get_prog_info(info->prog_id, &prog_info);
@@ -185,7 +185,7 @@ static int show_link_close_plain(int fd, struct bpf_link_info *info)
        switch (info->type) {
        case BPF_LINK_TYPE_RAW_TRACEPOINT:
                printf("\n\ttp '%s'  ",
-                      (const char *)info->raw_tracepoint.tp_name);
+                      (const char *)u64_to_ptr(info->raw_tracepoint.tp_name));
                break;
        case BPF_LINK_TYPE_TRACING:
                err = get_prog_info(info->prog_id, &prog_info);
index e3a79b5..c46e521 100644 (file)
 /* Make sure we do not use kernel-only integer typedefs */
 #pragma GCC poison u8 u16 u32 u64 s8 s16 s32 s64
 
-#define ptr_to_u64(ptr)        ((__u64)(unsigned long)(ptr))
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+       return (__u64)(unsigned long)ptr;
+}
+
+static inline void *u64_to_ptr(__u64 ptr)
+{
+       return (void *)(unsigned long)ptr;
+}
 
 #define NEXT_ARG()     ({ argc--; argv++; if (argc < 0) usage(); })
 #define NEXT_ARGP()    ({ (*argc)--; (*argv)++; if (*argc < 0) usage(); })
index 158995d..d393eb8 100644 (file)
@@ -428,14 +428,14 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
                        p_info("no instructions returned");
                        return -1;
                }
-               buf = (unsigned char *)(info->jited_prog_insns);
+               buf = u64_to_ptr(info->jited_prog_insns);
                member_len = info->jited_prog_len;
        } else {        /* DUMP_XLATED */
                if (info->xlated_prog_len == 0 || !info->xlated_prog_insns) {
                        p_err("error retrieving insn dump: kernel.kptr_restrict set?");
                        return -1;
                }
-               buf = (unsigned char *)info->xlated_prog_insns;
+               buf = u64_to_ptr(info->xlated_prog_insns);
                member_len = info->xlated_prog_len;
        }
 
@@ -444,7 +444,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
                return -1;
        }
 
-       func_info = (void *)info->func_info;
+       func_info = u64_to_ptr(info->func_info);
 
        if (info->nr_line_info) {
                prog_linfo = bpf_prog_linfo__new(info);
@@ -462,7 +462,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
 
                n = write(fd, buf, member_len);
                close(fd);
-               if (n != member_len) {
+               if (n != (ssize_t)member_len) {
                        p_err("error writing output file: %s",
                              n < 0 ? strerror(errno) : "short write");
                        return -1;
@@ -492,13 +492,13 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
                        __u32 i;
                        if (info->nr_jited_ksyms) {
                                kernel_syms_load(&dd);
-                               ksyms = (__u64 *) info->jited_ksyms;
+                               ksyms = u64_to_ptr(info->jited_ksyms);
                        }
 
                        if (json_output)
                                jsonw_start_array(json_wtr);
 
-                       lens = (__u32 *) info->jited_func_lens;
+                       lens = u64_to_ptr(info->jited_func_lens);
                        for (i = 0; i < info->nr_jited_func_lens; i++) {
                                if (ksyms) {
                                        sym = kernel_syms_search(&dd, ksyms[i]);
@@ -559,7 +559,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
        } else {
                kernel_syms_load(&dd);
                dd.nr_jited_ksyms = info->nr_jited_ksyms;
-               dd.jited_ksyms = (__u64 *) info->jited_ksyms;
+               dd.jited_ksyms = u64_to_ptr(info->jited_ksyms);
                dd.btf = btf;
                dd.func_info = func_info;
                dd.finfo_rec_size = info->func_info_rec_size;
@@ -1681,7 +1681,7 @@ static char *profile_target_name(int tgt_fd)
                goto out;
        }
 
-       func_info = (struct bpf_func_info *)(info_linear->info.func_info);
+       func_info = u64_to_ptr(info_linear->info.func_info);
        t = btf__type_by_id(btf, func_info[0].type_id);
        if (!t) {
                p_err("btf %d doesn't have type %d",
index 774f0b0..c1daf4d 100644 (file)
@@ -8,7 +8,7 @@ endif
 
 feature_check = $(eval $(feature_check_code))
 define feature_check_code
-  feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CC=$(CC) CXX=$(CXX) CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" CXXFLAGS="$(EXTRA_CXXFLAGS) $(FEATURE_CHECK_CXXFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
+  feature-$(1) := $(shell $(MAKE) OUTPUT=$(OUTPUT_FEATURES) CC="$(CC)" CXX="$(CXX)" CFLAGS="$(EXTRA_CFLAGS) $(FEATURE_CHECK_CFLAGS-$(1))" CXXFLAGS="$(EXTRA_CXXFLAGS) $(FEATURE_CHECK_CXXFLAGS-$(1))" LDFLAGS="$(LDFLAGS) $(FEATURE_CHECK_LDFLAGS-$(1))" -C $(feature_dir) $(OUTPUT_FEATURES)test-$1.bin >/dev/null 2>/dev/null && echo 1 || echo 0)
 endef
 
 feature_set = $(eval $(feature_set_code))
@@ -98,7 +98,8 @@ FEATURE_TESTS_EXTRA :=                  \
          llvm-version                   \
          clang                          \
          libbpf                         \
-         libpfm4
+         libpfm4                        \
+         libdebuginfod
 
 FEATURE_TESTS ?= $(FEATURE_TESTS_BASIC)
 
index 846ee13..d220fe9 100644 (file)
@@ -26,6 +26,7 @@ FILES=                                          \
          test-libelf-gelf_getnote.bin           \
          test-libelf-getshdrstrndx.bin          \
          test-libelf-mmap.bin                   \
+         test-libdebuginfod.bin                 \
          test-libnuma.bin                       \
          test-numa_num_possible_cpus.bin        \
          test-libperl.bin                       \
@@ -157,6 +158,9 @@ $(OUTPUT)test-libelf-gelf_getnote.bin:
 $(OUTPUT)test-libelf-getshdrstrndx.bin:
        $(BUILD) -lelf
 
+$(OUTPUT)test-libdebuginfod.bin:
+       $(BUILD) -ldebuginfod
+
 $(OUTPUT)test-libnuma.bin:
        $(BUILD) -lnuma
 
diff --git a/tools/build/feature/test-libdebuginfod.c b/tools/build/feature/test-libdebuginfod.c
new file mode 100644 (file)
index 0000000..da22548
--- /dev/null
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <elfutils/debuginfod.h>
+
+int main(void)
+{
+       debuginfod_client* c = debuginfod_begin();
+       return (long)c;
+}
index 4fdf303..f6d8603 100644 (file)
@@ -289,6 +289,7 @@ struct kvm_run {
                /* KVM_EXIT_FAIL_ENTRY */
                struct {
                        __u64 hardware_entry_failure_reason;
+                       __u32 cpu;
                } fail_entry;
                /* KVM_EXIT_EXCEPTION */
                struct {
@@ -1031,6 +1032,9 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PPC_SECURE_GUEST 181
 #define KVM_CAP_HALT_POLL 182
 #define KVM_CAP_ASYNC_PF_INT 183
+#define KVM_CAP_LAST_CPU 184
+#define KVM_CAP_SMALLER_MAXPHYADDR 185
+#define KVM_CAP_S390_DIAG318 186
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
index 0c23496..7523218 100644 (file)
@@ -91,6 +91,8 @@
 
 /* Use message type V2 */
 #define VHOST_BACKEND_F_IOTLB_MSG_V2 0x1
+/* IOTLB can accept batching hints */
+#define VHOST_BACKEND_F_IOTLB_BATCH  0x2
 
 #define VHOST_SET_BACKEND_FEATURES _IOW(VHOST_VIRTIO, 0x25, __u64)
 #define VHOST_GET_BACKEND_FEATURES _IOR(VHOST_VIRTIO, 0x26, __u64)
index bc14db7..e9a4ecd 100644 (file)
@@ -40,7 +40,7 @@
  * Helper macro to manipulate data structures
  */
 #ifndef offsetof
-#define offsetof(TYPE, MEMBER)  __builtin_offsetof(TYPE, MEMBER)
+#define offsetof(TYPE, MEMBER) ((unsigned long)&((TYPE *)0)->MEMBER)
 #endif
 #ifndef container_of
 #define container_of(ptr, type, member)                                \
index 4843e44..7dfca70 100644 (file)
@@ -41,6 +41,7 @@ struct btf {
        __u32 types_size;
        __u32 data_size;
        int fd;
+       int ptr_sz;
 };
 
 static inline __u64 ptr_to_u64(const void *ptr)
@@ -221,6 +222,70 @@ const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
        return btf->types[type_id];
 }
 
+static int determine_ptr_size(const struct btf *btf)
+{
+       const struct btf_type *t;
+       const char *name;
+       int i;
+
+       for (i = 1; i <= btf->nr_types; i++) {
+               t = btf__type_by_id(btf, i);
+               if (!btf_is_int(t))
+                       continue;
+
+               name = btf__name_by_offset(btf, t->name_off);
+               if (!name)
+                       continue;
+
+               if (strcmp(name, "long int") == 0 ||
+                   strcmp(name, "long unsigned int") == 0) {
+                       if (t->size != 4 && t->size != 8)
+                               continue;
+                       return t->size;
+               }
+       }
+
+       return -1;
+}
+
+static size_t btf_ptr_sz(const struct btf *btf)
+{
+       if (!btf->ptr_sz)
+               ((struct btf *)btf)->ptr_sz = determine_ptr_size(btf);
+       return btf->ptr_sz < 0 ? sizeof(void *) : btf->ptr_sz;
+}
+
+/* Return pointer size this BTF instance assumes. The size is heuristically
+ * determined by looking for 'long' or 'unsigned long' integer type and
+ * recording its size in bytes. If BTF type information doesn't have any such
+ * type, this function returns 0. In the latter case, native architecture's
+ * pointer size is assumed, so will be either 4 or 8, depending on
+ * architecture that libbpf was compiled for. It's possible to override
+ * guessed value by using btf__set_pointer_size() API.
+ */
+size_t btf__pointer_size(const struct btf *btf)
+{
+       if (!btf->ptr_sz)
+               ((struct btf *)btf)->ptr_sz = determine_ptr_size(btf);
+
+       if (btf->ptr_sz < 0)
+               /* not enough BTF type info to guess */
+               return 0;
+
+       return btf->ptr_sz;
+}
+
+/* Override or set pointer size in bytes. Only values of 4 and 8 are
+ * supported.
+ */
+int btf__set_pointer_size(struct btf *btf, size_t ptr_sz)
+{
+       if (ptr_sz != 4 && ptr_sz != 8)
+               return -EINVAL;
+       btf->ptr_sz = ptr_sz;
+       return 0;
+}
+
 static bool btf_type_is_void(const struct btf_type *t)
 {
        return t == &btf_void || btf_is_fwd(t);
@@ -253,7 +318,7 @@ __s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
                        size = t->size;
                        goto done;
                case BTF_KIND_PTR:
-                       size = sizeof(void *);
+                       size = btf_ptr_sz(btf);
                        goto done;
                case BTF_KIND_TYPEDEF:
                case BTF_KIND_VOLATILE:
@@ -293,9 +358,9 @@ int btf__align_of(const struct btf *btf, __u32 id)
        switch (kind) {
        case BTF_KIND_INT:
        case BTF_KIND_ENUM:
-               return min(sizeof(void *), (size_t)t->size);
+               return min(btf_ptr_sz(btf), (size_t)t->size);
        case BTF_KIND_PTR:
-               return sizeof(void *);
+               return btf_ptr_sz(btf);
        case BTF_KIND_TYPEDEF:
        case BTF_KIND_VOLATILE:
        case BTF_KIND_CONST:
@@ -533,6 +598,18 @@ struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext)
        if (IS_ERR(btf))
                goto done;
 
+       switch (gelf_getclass(elf)) {
+       case ELFCLASS32:
+               btf__set_pointer_size(btf, 4);
+               break;
+       case ELFCLASS64:
+               btf__set_pointer_size(btf, 8);
+               break;
+       default:
+               pr_warn("failed to get ELF class (bitness) for %s\n", path);
+               break;
+       }
+
        if (btf_ext && btf_ext_data) {
                *btf_ext = btf_ext__new(btf_ext_data->d_buf,
                                        btf_ext_data->d_size);
index f4a1a1d..1ca1444 100644 (file)
@@ -76,6 +76,8 @@ LIBBPF_API __s32 btf__find_by_name_kind(const struct btf *btf,
 LIBBPF_API __u32 btf__get_nr_types(const struct btf *btf);
 LIBBPF_API const struct btf_type *btf__type_by_id(const struct btf *btf,
                                                  __u32 id);
+LIBBPF_API size_t btf__pointer_size(const struct btf *btf);
+LIBBPF_API int btf__set_pointer_size(struct btf *btf, size_t ptr_sz);
 LIBBPF_API __s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
 LIBBPF_API int btf__resolve_type(const struct btf *btf, __u32 type_id);
 LIBBPF_API int btf__align_of(const struct btf *btf, __u32 id);
index cf71116..fe39bd7 100644 (file)
@@ -13,6 +13,7 @@
 #include <errno.h>
 #include <linux/err.h>
 #include <linux/btf.h>
+#include <linux/kernel.h>
 #include "btf.h"
 #include "hashmap.h"
 #include "libbpf.h"
@@ -60,6 +61,7 @@ struct btf_dump {
        const struct btf_ext *btf_ext;
        btf_dump_printf_fn_t printf_fn;
        struct btf_dump_opts opts;
+       int ptr_sz;
        bool strip_mods;
 
        /* per-type auxiliary state */
@@ -138,6 +140,7 @@ struct btf_dump *btf_dump__new(const struct btf *btf,
        d->btf_ext = btf_ext;
        d->printf_fn = printf_fn;
        d->opts.ctx = opts ? opts->ctx : NULL;
+       d->ptr_sz = btf__pointer_size(btf) ? : sizeof(void *);
 
        d->type_names = hashmap__new(str_hash_fn, str_equal_fn, NULL);
        if (IS_ERR(d->type_names)) {
@@ -549,6 +552,9 @@ static int btf_dump_order_type(struct btf_dump *d, __u32 id, bool through_ptr)
        }
 }
 
+static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
+                                         const struct btf_type *t);
+
 static void btf_dump_emit_struct_fwd(struct btf_dump *d, __u32 id,
                                     const struct btf_type *t);
 static void btf_dump_emit_struct_def(struct btf_dump *d, __u32 id,
@@ -671,6 +677,9 @@ static void btf_dump_emit_type(struct btf_dump *d, __u32 id, __u32 cont_id)
 
        switch (kind) {
        case BTF_KIND_INT:
+               /* Emit type alias definitions if necessary */
+               btf_dump_emit_missing_aliases(d, id, t);
+
                tstate->emit_state = EMITTED;
                break;
        case BTF_KIND_ENUM:
@@ -797,7 +806,7 @@ static void btf_dump_emit_bit_padding(const struct btf_dump *d,
                                      int align, int lvl)
 {
        int off_diff = m_off - cur_off;
-       int ptr_bits = sizeof(void *) * 8;
+       int ptr_bits = d->ptr_sz * 8;
 
        if (off_diff <= 0)
                /* no gap */
@@ -870,7 +879,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
                        btf_dump_printf(d, ": %d", m_sz);
                        off = m_off + m_sz;
                } else {
-                       m_sz = max(0, btf__resolve_size(d->btf, m->type));
+                       m_sz = max(0LL, btf__resolve_size(d->btf, m->type));
                        off = m_off + m_sz * 8;
                }
                btf_dump_printf(d, ";");
@@ -890,6 +899,32 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
                btf_dump_printf(d, " __attribute__((packed))");
 }
 
+static const char *missing_base_types[][2] = {
+       /*
+        * GCC emits typedefs to its internal __PolyX_t types when compiling Arm
+        * SIMD intrinsics. Alias them to standard base types.
+        */
+       { "__Poly8_t",          "unsigned char" },
+       { "__Poly16_t",         "unsigned short" },
+       { "__Poly64_t",         "unsigned long long" },
+       { "__Poly128_t",        "unsigned __int128" },
+};
+
+static void btf_dump_emit_missing_aliases(struct btf_dump *d, __u32 id,
+                                         const struct btf_type *t)
+{
+       const char *name = btf_dump_type_name(d, id);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(missing_base_types); i++) {
+               if (strcmp(name, missing_base_types[i][0]) == 0) {
+                       btf_dump_printf(d, "typedef %s %s;\n\n",
+                                       missing_base_types[i][1], name);
+                       break;
+               }
+       }
+}
+
 static void btf_dump_emit_enum_fwd(struct btf_dump *d, __u32 id,
                                   const struct btf_type *t)
 {
index 0a06124..5d20b2d 100644 (file)
@@ -2434,6 +2434,8 @@ static int bpf_object__init_btf(struct bpf_object *obj,
                                BTF_ELF_SEC, err);
                        goto out;
                }
+               /* enforce 8-byte pointers for BPF-targeted BTFs */
+               btf__set_pointer_size(obj->btf, 8);
                err = 0;
        }
        if (btf_ext_data) {
@@ -2542,6 +2544,8 @@ static int bpf_object__sanitize_and_load_btf(struct bpf_object *obj)
                if (IS_ERR(kern_btf))
                        return PTR_ERR(kern_btf);
 
+               /* enforce 8-byte pointers for BPF-targeted BTFs */
+               btf__set_pointer_size(obj->btf, 8);
                bpf_object__sanitize_btf(obj, kern_btf);
        }
 
@@ -3478,10 +3482,11 @@ bpf_object__probe_global_data(struct bpf_object *obj)
 
        map = bpf_create_map_xattr(&map_attr);
        if (map < 0) {
-               cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));
+               ret = -errno;
+               cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg));
                pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n",
-                       __func__, cp, errno);
-               return -errno;
+                       __func__, cp, -ret);
+               return ret;
        }
 
        insns[0].imm = map;
@@ -5194,7 +5199,8 @@ static int bpf_object__collect_st_ops_relos(struct bpf_object *obj,
 static int bpf_object__collect_map_relos(struct bpf_object *obj,
                                         GElf_Shdr *shdr, Elf_Data *data)
 {
-       int i, j, nrels, new_sz, ptr_sz = sizeof(void *);
+       const int bpf_ptr_sz = 8, host_ptr_sz = sizeof(void *);
+       int i, j, nrels, new_sz;
        const struct btf_var_secinfo *vi = NULL;
        const struct btf_type *sec, *var, *def;
        const struct btf_member *member;
@@ -5243,7 +5249,7 @@ static int bpf_object__collect_map_relos(struct bpf_object *obj,
 
                        vi = btf_var_secinfos(sec) + map->btf_var_idx;
                        if (vi->offset <= rel.r_offset &&
-                           rel.r_offset + sizeof(void *) <= vi->offset + vi->size)
+                           rel.r_offset + bpf_ptr_sz <= vi->offset + vi->size)
                                break;
                }
                if (j == obj->nr_maps) {
@@ -5279,17 +5285,20 @@ static int bpf_object__collect_map_relos(struct bpf_object *obj,
                        return -EINVAL;
 
                moff = rel.r_offset - vi->offset - moff;
-               if (moff % ptr_sz)
+               /* here we use BPF pointer size, which is always 64 bit, as we
+                * are parsing ELF that was built for BPF target
+                */
+               if (moff % bpf_ptr_sz)
                        return -EINVAL;
-               moff /= ptr_sz;
+               moff /= bpf_ptr_sz;
                if (moff >= map->init_slots_sz) {
                        new_sz = moff + 1;
-                       tmp = realloc(map->init_slots, new_sz * ptr_sz);
+                       tmp = realloc(map->init_slots, new_sz * host_ptr_sz);
                        if (!tmp)
                                return -ENOMEM;
                        map->init_slots = tmp;
                        memset(map->init_slots + map->init_slots_sz, 0,
-                              (new_sz - map->init_slots_sz) * ptr_sz);
+                              (new_sz - map->init_slots_sz) * host_ptr_sz);
                        map->init_slots_sz = new_sz;
                }
                map->init_slots[moff] = targ_map;
@@ -6012,9 +6021,10 @@ int bpf_program__pin_instance(struct bpf_program *prog, const char *path,
        }
 
        if (bpf_obj_pin(prog->instances.fds[instance], path)) {
-               cp = libbpf_strerror_r(errno, errmsg, sizeof(errmsg));
+               err = -errno;
+               cp = libbpf_strerror_r(err, errmsg, sizeof(errmsg));
                pr_warn("failed to pin program: %s\n", cp);
-               return -errno;
+               return err;
        }
        pr_debug("pinned program '%s'\n", path);
 
index 0c4722b..e35bd6c 100644 (file)
@@ -295,5 +295,7 @@ LIBBPF_0.1.0 {
                bpf_program__set_sk_lookup;
                btf__parse;
                btf__parse_raw;
+               btf__pointer_size;
                btf__set_fd;
+               btf__set_pointer_size;
 } LIBBPF_0.0.9;
index cae9757..8b75efc 100644 (file)
@@ -7,13 +7,13 @@ libperf-counting - counting interface
 
 DESCRIPTION
 -----------
-The counting interface provides API to meassure and get count for specific perf events.
+The counting interface provides API to measure and get count for specific perf events.
 
 The following test tries to explain count on `counting.c` example.
 
 It is by no means complete guide to counting, but shows libperf basic API for counting.
 
-The `counting.c` comes with libbperf package and can be compiled and run like:
+The `counting.c` comes with libperf package and can be compiled and run like:
 
 [source,bash]
 --
@@ -26,7 +26,8 @@ count 176242, enabled 176242, run 176242
 It requires root access, because of the `PERF_COUNT_SW_CPU_CLOCK` event,
 which is available only for root.
 
-The `counting.c` example monitors two events on the current process and displays their count, in a nutshel it:
+The `counting.c` example monitors two events on the current process and displays
+their count, in a nutshell it:
 
 * creates events
 * adds them to the event list
@@ -152,7 +153,7 @@ Configure event list with the thread map and open events:
 --
 
 Both events are created as disabled (note the `disabled = 1` assignment above),
-so we need to enable the whole list explicitely (both events).
+so we need to enable the whole list explicitly (both events).
 
 From this moment events are counting and we can do our workload.
 
@@ -167,7 +168,8 @@ When we are done we disable the events list.
  79         perf_evlist__disable(evlist);
 --
 
-Now we need to get the counts from events, following code iterates throught the events list and read counts:
+Now we need to get the counts from events, following code iterates through the
+events list and read counts:
 
 [source,c]
 --
@@ -178,7 +180,7 @@ Now we need to get the counts from events, following code iterates throught the
  85         }
 --
 
-And finaly cleanup.
+And finally cleanup.
 
 We close the whole events list (both events) and remove it together with the threads map:
 
index d71a7b4..d6ca24f 100644 (file)
@@ -8,13 +8,13 @@ libperf-sampling - sampling interface
 
 DESCRIPTION
 -----------
-The sampling interface provides API to meassure and get count for specific perf events.
+The sampling interface provides API to measure and get count for specific perf events.
 
 The following test tries to explain count on `sampling.c` example.
 
 It is by no means complete guide to sampling, but shows libperf basic API for sampling.
 
-The `sampling.c` comes with libbperf package and can be compiled and run like:
+The `sampling.c` comes with libperf package and can be compiled and run like:
 
 [source,bash]
 --
@@ -33,7 +33,8 @@ cpu   0, pid   4465, tid   4470, ip         7f84fe0ebebf, period             176
 
 It requires root access, because it uses hardware cycles event.
 
-The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a nutshel it:
+The `sampling.c` example profiles/samples all CPUs with hardware cycles, in a
+nutshell it:
 
 - creates events
 - adds them to the event list
@@ -90,7 +91,7 @@ Once the setup is complete we start by defining cycles event using the `struct p
  36         };
 --
 
-Next step is to prepare cpus map.
+Next step is to prepare CPUs map.
 
 In this case we will monitor all the available CPUs:
 
@@ -152,7 +153,7 @@ Once the events list is open, we can create memory maps AKA perf ring buffers:
 --
 
 The event is created as disabled (note the `disabled = 1` assignment above),
-so we need to enable the events list explicitely.
+so we need to enable the events list explicitly.
 
 From this moment the cycles event is sampling.
 
@@ -212,7 +213,7 @@ Each sample needs to get parsed:
 106                                 cpu, pid, tid, ip, period);
 --
 
-And finaly cleanup.
+And finally cleanup.
 
 We close the whole events list (both events) and remove it together with the threads map:
 
index 5a6bb51..0c74c30 100644 (file)
@@ -29,7 +29,7 @@ SYNOPSIS
   void libperf_init(libperf_print_fn_t fn);
 --
 
-*API to handle cpu maps:*
+*API to handle CPU maps:*
 
 [source,c]
 --
@@ -217,7 +217,7 @@ Following objects are key to the libperf interface:
 
 [horizontal]
 
-struct perf_cpu_map:: Provides a cpu list abstraction.
+struct perf_cpu_map:: Provides a CPU list abstraction.
 
 struct perf_thread_map:: Provides a thread list abstraction.
 
index c7d3df5..76408d9 100644 (file)
@@ -614,8 +614,9 @@ trace.*::
 
 ftrace.*::
        ftrace.tracer::
-               Can be used to select the default tracer. Possible values are
-               'function' and 'function_graph'.
+               Can be used to select the default tracer when neither -G nor
+               -F option is not specified. Possible values are 'function' and
+               'function_graph'.
 
 llvm.*::
        llvm.clang-path::
index b80c843..78358af 100644 (file)
@@ -24,16 +24,28 @@ OPTIONS
 
 -t::
 --tracer=::
-       Tracer to use: function_graph or function.
+       Tracer to use when neither -G nor -F option is not
+       specified: function_graph or function.
 
 -v::
 --verbose=::
         Verbosity level.
 
+-F::
+--funcs::
+        List all available functions to trace.
+
 -p::
 --pid=::
        Trace on existing process id (comma separated list).
 
+--tid=::
+       Trace on existing thread id (comma separated list).
+
+-D::
+--delay::
+       Time (ms) to wait before starting tracing after program start.
+
 -a::
 --all-cpus::
        Force system-wide collection.  Scripts run without a <command>
@@ -48,39 +60,58 @@ OPTIONS
        Ranges of CPUs are specified with -: 0-2.
        Default is to trace on all online CPUs.
 
+-m::
+--buffer-size::
+       Set the size of per-cpu tracing buffer, <size> is expected to
+       be a number with appended unit character - B/K/M/G.
+
+--inherit::
+       Trace children processes spawned by our target.
+
 -T::
 --trace-funcs=::
-       Only trace functions given by the argument.  Multiple functions
-       can be given by using this option more than once.  The function
-       argument also can be a glob pattern.  It will be passed to
-       'set_ftrace_filter' in tracefs.
+       Select function tracer and set function filter on the given
+       function (or a glob pattern). Multiple functions can be given
+       by using this option more than once. The function argument also
+       can be a glob pattern. It will be passed to 'set_ftrace_filter'
+       in tracefs.
 
 -N::
 --notrace-funcs=::
-       Do not trace functions given by the argument.  Like -T option,
-       this can be used more than once to specify multiple functions
-       (or glob patterns).  It will be passed to 'set_ftrace_notrace'
-       in tracefs.
+       Select function tracer and do not trace functions given by the
+       argument.  Like -T option, this can be used more than once to
+       specify multiple functions (or glob patterns).  It will be
+       passed to 'set_ftrace_notrace' in tracefs.
+
+--func-opts::
+       List of options allowed to set:
+         call-graph - Display kernel stack trace for function tracer.
+         irq-info   - Display irq context info for function tracer.
 
 -G::
 --graph-funcs=::
-       Set graph filter on the given function (or a glob pattern).
-       This is useful for the function_graph tracer only and enables
-       tracing for functions executed from the given function.
-       This can be used more than once to specify multiple functions.
-       It will be passed to 'set_graph_function' in tracefs.
+       Select function_graph tracer and set graph filter on the given
+       function (or a glob pattern). This is useful to trace for
+       functions executed from the given function. This can be used more
+       than once to specify multiple functions. It will be passed to
+       'set_graph_function' in tracefs.
 
 -g::
 --nograph-funcs=::
-       Set graph notrace filter on the given function (or a glob pattern).
-       Like -G option, this is useful for the function_graph tracer only
-       and disables tracing for function executed from the given function.
-       This can be used more than once to specify multiple functions.
-       It will be passed to 'set_graph_notrace' in tracefs.
+       Select function_graph tracer and set graph notrace filter on the
+       given function (or a glob pattern). Like -G option, this is useful
+       for the function_graph tracer only and disables tracing for function
+       executed from the given function. This can be used more than once to
+       specify multiple functions. It will be passed to 'set_graph_notrace'
+       in tracefs.
 
--D::
---graph-depth=::
-       Set max depth for function graph tracer to follow
+--graph-opts::
+       List of options allowed to set:
+         nosleep-time - Measure on-CPU time only for function_graph tracer.
+         noirqs       - Ignore functions that happen inside interrupt.
+         verbose      - Show process names, PIDs, timestamps, etc.
+         thresh=<n>   - Setup trace duration threshold in microseconds.
+         depth=<n>    - Set max depth for function graph tracer to follow.
 
 SEE ALSO
 --------
index 5136338..190be4f 100644 (file)
@@ -501,6 +501,14 @@ ifndef NO_LIBELF
     CFLAGS += -DHAVE_ELF_GETSHDRSTRNDX_SUPPORT
   endif
 
+  ifndef NO_LIBDEBUGINFOD
+    $(call feature_check,libdebuginfod)
+    ifeq ($(feature-libdebuginfod), 1)
+      CFLAGS += -DHAVE_DEBUGINFOD_SUPPORT
+      EXTLIBS += -ldebuginfod
+    endif
+  endif
+
   ifndef NO_DWARF
     ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
       msg := $(warning DWARF register mappings have not been defined for architecture $(SRCARCH), DWARF support disabled);
index 86dbb51..6031167 100644 (file)
@@ -124,6 +124,8 @@ include ../scripts/utilities.mak
 #
 # Define LIBPFM4 to enable libpfm4 events extension.
 #
+# Define NO_LIBDEBUGINFOD if you do not want support debuginfod
+#
 
 # As per kernel Makefile, avoid funny character set dependencies
 unexport LC_ALL
@@ -418,6 +420,7 @@ export INSTALL SHELL_PATH
 
 SHELL = $(SHELL_PATH)
 
+beauty_linux_dir := $(srctree)/tools/perf/trace/beauty/include/linux/
 linux_uapi_dir := $(srctree)/tools/include/uapi/linux
 asm_generic_uapi_dir := $(srctree)/tools/include/uapi/asm-generic
 arch_asm_uapi_dir := $(srctree)/tools/arch/$(SRCARCH)/include/uapi/asm/
@@ -501,6 +504,12 @@ socket_ipproto_tbl := $(srctree)/tools/perf/trace/beauty/socket_ipproto.sh
 $(socket_ipproto_array): $(linux_uapi_dir)/in.h $(socket_ipproto_tbl)
        $(Q)$(SHELL) '$(socket_ipproto_tbl)' $(linux_uapi_dir) > $@
 
+socket_arrays := $(beauty_outdir)/socket_arrays.c
+socket_tbl := $(srctree)/tools/perf/trace/beauty/socket.sh
+
+$(socket_arrays): $(beauty_linux_dir)/socket.h $(socket_tbl)
+       $(Q)$(SHELL) '$(socket_tbl)' $(beauty_linux_dir) > $@
+
 vhost_virtio_ioctl_array := $(beauty_ioctl_outdir)/vhost_virtio_ioctl_array.c
 vhost_virtio_hdr_dir := $(srctree)/tools/include/uapi/linux
 vhost_virtio_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/vhost_virtio_ioctl.sh
@@ -697,6 +706,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc
        $(kcmp_type_array) \
        $(kvm_ioctl_array) \
        $(socket_ipproto_array) \
+       $(socket_arrays) \
        $(vhost_virtio_ioctl_array) \
        $(madvise_behavior_array) \
        $(mmap_flags_array) \
@@ -1006,6 +1016,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea
                $(OUTPUT)$(kvm_ioctl_array) \
                $(OUTPUT)$(kcmp_type_array) \
                $(OUTPUT)$(socket_ipproto_array) \
+               $(OUTPUT)$(socket_arrays) \
                $(OUTPUT)$(vhost_virtio_ioctl_array) \
                $(OUTPUT)$(perf_ioctl_array) \
                $(OUTPUT)$(prctl_option_array) \
index b190f2e..3ca6fe0 100644 (file)
 146    common  writev                          sys_writev                      compat_sys_writev
 147    common  getsid                          sys_getsid
 148    common  fdatasync                       sys_fdatasync
-149    nospu   _sysctl                         sys_sysctl                      compat_sys_sysctl
+149    nospu   _sysctl                         sys_ni_syscall
 150    common  mlock                           sys_mlock
 151    common  munlock                         sys_munlock
 152    common  mlockall                        sys_mlockall
index 56ae24b..6a0bbea 100644 (file)
 146  common    writev                  sys_writev                      compat_sys_writev
 147  common    getsid                  sys_getsid                      sys_getsid
 148  common    fdatasync               sys_fdatasync                   sys_fdatasync
-149  common    _sysctl                 sys_sysctl                      compat_sys_sysctl
+149  common    _sysctl                 -                               -
 150  common    mlock                   sys_mlock                       compat_sys_mlock
 151  common    munlock                 sys_munlock                     compat_sys_munlock
 152  common    mlockall                sys_mlockall                    sys_mlockall
index 9d82078..f30d6ae 100644 (file)
 153    common  vhangup                 sys_vhangup
 154    common  modify_ldt              sys_modify_ldt
 155    common  pivot_root              sys_pivot_root
-156    64      _sysctl                 sys_sysctl
+156    64      _sysctl                 sys_ni_syscall
 157    common  prctl                   sys_prctl
 158    common  arch_prctl              sys_arch_prctl
 159    common  adjtimex                sys_adjtimex
index fa90f3e..73b5bcc 100644 (file)
@@ -17,9 +17,9 @@ static unsigned int inner_iterations = 100000;
 
 static const struct option options[] = {
        OPT_UINTEGER('i', "outer-iterations", &outer_iterations,
-               "Number of outerer iterations used"),
+               "Number of outer iterations used"),
        OPT_UINTEGER('j', "inner-iterations", &inner_iterations,
-               "Number of outerer iterations used"),
+               "Number of inner iterations used"),
        OPT_END()
 };
 
index 9235b76..19d45c3 100644 (file)
@@ -223,12 +223,8 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
        return 0;
 }
 
-static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
+static void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst)
 {
-       u64 cycle_start = 0ULL, cycle_end = 0ULL;
-       memcpy_t fn = r->fn.memcpy;
-       int i;
-
        /* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
        memset(src, 0, size);
 
@@ -237,6 +233,15 @@ static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, vo
         * to not measure page fault overhead:
         */
        fn(dst, src, size);
+}
+
+static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
+{
+       u64 cycle_start = 0ULL, cycle_end = 0ULL;
+       memcpy_t fn = r->fn.memcpy;
+       int i;
+
+       memcpy_prefault(fn, size, src, dst);
 
        cycle_start = get_cycles();
        for (i = 0; i < nr_loops; ++i)
@@ -252,11 +257,7 @@ static double do_memcpy_gettimeofday(const struct function *r, size_t size, void
        memcpy_t fn = r->fn.memcpy;
        int i;
 
-       /*
-        * We prefault the freshly allocated memory range here,
-        * to not measure page fault overhead:
-        */
-       fn(dst, src, size);
+       memcpy_prefault(fn, size, src, dst);
 
        BUG_ON(gettimeofday(&tv_start, NULL));
        for (i = 0; i < nr_loops; ++i)
index 5797253..f85bcec 100644 (file)
@@ -247,17 +247,22 @@ static int is_node_present(int node)
  */
 static bool node_has_cpus(int node)
 {
-       struct bitmask *cpu = numa_allocate_cpumask();
-       unsigned int i;
+       struct bitmask *cpumask = numa_allocate_cpumask();
+       bool ret = false; /* fall back to nocpus */
+       int cpu;
 
-       if (cpu && !numa_node_to_cpus(node, cpu)) {
-               for (i = 0; i < cpu->size; i++) {
-                       if (numa_bitmask_isbitset(cpu, i))
-                               return true;
+       BUG_ON(!cpumask);
+       if (!numa_node_to_cpus(node, cpumask)) {
+               for (cpu = 0; cpu < (int)cpumask->size; cpu++) {
+                       if (numa_bitmask_isbitset(cpumask, cpu)) {
+                               ret = true;
+                               break;
+                       }
                }
        }
+       numa_free_cpumask(cpumask);
 
-       return false; /* lets fall back to nocpus safely */
+       return ret;
 }
 
 static cpu_set_t bind_to_cpu(int target_cpu)
@@ -288,14 +293,10 @@ static cpu_set_t bind_to_cpu(int target_cpu)
 
 static cpu_set_t bind_to_node(int target_node)
 {
-       int cpus_per_node = g->p.nr_cpus / nr_numa_nodes();
        cpu_set_t orig_mask, mask;
        int cpu;
        int ret;
 
-       BUG_ON(cpus_per_node * nr_numa_nodes() != g->p.nr_cpus);
-       BUG_ON(!cpus_per_node);
-
        ret = sched_getaffinity(0, sizeof(orig_mask), &orig_mask);
        BUG_ON(ret);
 
@@ -305,13 +306,16 @@ static cpu_set_t bind_to_node(int target_node)
                for (cpu = 0; cpu < g->p.nr_cpus; cpu++)
                        CPU_SET(cpu, &mask);
        } else {
-               int cpu_start = (target_node + 0) * cpus_per_node;
-               int cpu_stop  = (target_node + 1) * cpus_per_node;
+               struct bitmask *cpumask = numa_allocate_cpumask();
 
-               BUG_ON(cpu_stop > g->p.nr_cpus);
-
-               for (cpu = cpu_start; cpu < cpu_stop; cpu++)
-                       CPU_SET(cpu, &mask);
+               BUG_ON(!cpumask);
+               if (!numa_node_to_cpus(target_node, cpumask)) {
+                       for (cpu = 0; cpu < (int)cpumask->size; cpu++) {
+                               if (numa_bitmask_isbitset(cpumask, cpu))
+                                       CPU_SET(cpu, &mask);
+                       }
+               }
+               numa_free_cpumask(cpumask);
        }
 
        ret = sched_setaffinity(0, sizeof(mask), &mask);
@@ -729,8 +733,6 @@ static int parse_nodes_opt(const struct option *opt __maybe_unused,
                return -1;
 
        return parse_node_list(arg);
-
-       return 0;
 }
 
 #define BIT(x) (1ul << x)
@@ -813,12 +815,12 @@ static u64 do_work(u8 *__data, long bytes, int nr, int nr_max, int loop, u64 val
                        }
                }
        } else if (!g->p.data_backwards || (nr + loop) & 1) {
+               /* Process data forwards: */
 
                d0 = data + off;
                d  = data + off + 1;
                d1 = data + words;
 
-               /* Process data forwards: */
                for (;;) {
                        if (unlikely(d >= d1))
                                d = data;
@@ -836,7 +838,6 @@ static u64 do_work(u8 *__data, long bytes, int nr, int nr_max, int loop, u64 val
                d  = data + off - 1;
                d1 = data + words;
 
-               /* Process data forwards: */
                for (;;) {
                        if (unlikely(d < data))
                                d = data + words-1;
@@ -1733,12 +1734,12 @@ err:
  */
 static const char *tests[][MAX_ARGS] = {
    /* Basic single-stream NUMA bandwidth measurements: */
-   { "RAM-bw-local,",    "mem",  "-p",  "1",  "-t",  "1", "-P", "1024",
+   { "RAM-bw-local,",     "mem",  "-p",  "1",  "-t",  "1", "-P", "1024",
                          "-C" ,   "0", "-M",   "0", OPT_BW_RAM },
    { "RAM-bw-local-NOTHP,",
                          "mem",  "-p",  "1",  "-t",  "1", "-P", "1024",
                          "-C" ,   "0", "-M",   "0", OPT_BW_RAM_NOTHP },
-   { "RAM-bw-remote,",   "mem",  "-p",  "1",  "-t",  "1", "-P", "1024",
+   { "RAM-bw-remote,",    "mem",  "-p",  "1",  "-t",  "1", "-P", "1024",
                          "-C" ,   "0", "-M",   "1", OPT_BW_RAM },
 
    /* 2-stream NUMA bandwidth measurements: */
@@ -1755,7 +1756,7 @@ static const char *tests[][MAX_ARGS] = {
    { " 1x3-convergence,", "mem",  "-p",  "1", "-t",  "3", "-P",  "512", OPT_CONV },
    { " 1x4-convergence,", "mem",  "-p",  "1", "-t",  "4", "-P",  "512", OPT_CONV },
    { " 1x6-convergence,", "mem",  "-p",  "1", "-t",  "6", "-P", "1020", OPT_CONV },
-   { " 2x3-convergence,", "mem",  "-p",  "3", "-t",  "3", "-P", "1020", OPT_CONV },
+   { " 2x3-convergence,", "mem",  "-p",  "2", "-t",  "3", "-P", "1020", OPT_CONV },
    { " 3x3-convergence,", "mem",  "-p",  "3", "-t",  "3", "-P", "1020", OPT_CONV },
    { " 4x4-convergence,", "mem",  "-p",  "4", "-t",  "4", "-P",  "512", OPT_CONV },
    { " 4x4-convergence-NOTHP,",
@@ -1780,24 +1781,24 @@ static const char *tests[][MAX_ARGS] = {
                          "mem",  "-p",  "8", "-t",  "1", "-P", " 512", OPT_BW_NOTHP },
    { "16x1-bw-process,",  "mem",  "-p", "16", "-t",  "1", "-P",  "256", OPT_BW },
 
-   { " 4x1-bw-thread,",          "mem",  "-p",  "1", "-t",  "4", "-T",  "256", OPT_BW },
-   { " 8x1-bw-thread,",          "mem",  "-p",  "1", "-t",  "8", "-T",  "256", OPT_BW },
-   { "16x1-bw-thread,",   "mem",  "-p",  "1", "-t", "16", "-T",  "128", OPT_BW },
-   { "32x1-bw-thread,",   "mem",  "-p",  "1", "-t", "32", "-T",   "64", OPT_BW },
+   { " 1x4-bw-thread,",   "mem",  "-p",  "1", "-t",  "4", "-T",  "256", OPT_BW },
+   { " 1x8-bw-thread,",   "mem",  "-p",  "1", "-t",  "8", "-T",  "256", OPT_BW },
+   { "1x16-bw-thread,",   "mem",  "-p",  "1", "-t", "16", "-T",  "128", OPT_BW },
+   { "1x32-bw-thread,",   "mem",  "-p",  "1", "-t", "32", "-T",   "64", OPT_BW },
 
-   { " 2x3-bw-thread,",          "mem",  "-p",  "2", "-t",  "3", "-P",  "512", OPT_BW },
-   { " 4x4-bw-thread,",          "mem",  "-p",  "4", "-t",  "4", "-P",  "512", OPT_BW },
-   { " 4x6-bw-thread,",          "mem",  "-p",  "4", "-t",  "6", "-P",  "512", OPT_BW },
-   { " 4x8-bw-thread,",          "mem",  "-p",  "4", "-t",  "8", "-P",  "512", OPT_BW },
-   { " 4x8-bw-thread-NOTHP,",
+   { " 2x3-bw-process,",  "mem",  "-p",  "2", "-t",  "3", "-P",  "512", OPT_BW },
+   { " 4x4-bw-process,",  "mem",  "-p",  "4", "-t",  "4", "-P",  "512", OPT_BW },
+   { " 4x6-bw-process,",  "mem",  "-p",  "4", "-t",  "6", "-P",  "512", OPT_BW },
+   { " 4x8-bw-process,",  "mem",  "-p",  "4", "-t",  "8", "-P",  "512", OPT_BW },
+   { " 4x8-bw-process-NOTHP,",
                          "mem",  "-p",  "4", "-t",  "8", "-P",  "512", OPT_BW_NOTHP },
-   { " 3x3-bw-thread,",          "mem",  "-p",  "3", "-t",  "3", "-P",  "512", OPT_BW },
-   { " 5x5-bw-thread,",          "mem",  "-p",  "5", "-t",  "5", "-P",  "512", OPT_BW },
+   { " 3x3-bw-process,",  "mem",  "-p",  "3", "-t",  "3", "-P",  "512", OPT_BW },
+   { " 5x5-bw-process,",  "mem",  "-p",  "5", "-t",  "5", "-P",  "512", OPT_BW },
 
-   { "2x16-bw-thread,",   "mem",  "-p",  "2", "-t", "16", "-P",  "512", OPT_BW },
-   { "1x32-bw-thread,",   "mem",  "-p",  "1", "-t", "32", "-P", "2048", OPT_BW },
+   { "2x16-bw-process,",  "mem",  "-p",  "2", "-t", "16", "-P",  "512", OPT_BW },
+   { "1x32-bw-process,",  "mem",  "-p",  "1", "-t", "32", "-P", "2048", OPT_BW },
 
-   { "numa02-bw,",       "mem",  "-p",  "1", "-t", "32", "-T",   "32", OPT_BW },
+   { "numa02-bw,",        "mem",  "-p",  "1", "-t", "32", "-T",   "32", OPT_BW },
    { "numa02-bw-NOTHP,",  "mem",  "-p",  "1", "-t", "32", "-T",   "32", OPT_BW_NOTHP },
    { "numa01-bw-thread,", "mem",  "-p",  "2", "-t", "16", "-T",  "192", OPT_BW },
    { "numa01-bw-thread-NOTHP,",
index 2bfc1b0..1d44bc2 100644 (file)
@@ -3,6 +3,7 @@
  * builtin-ftrace.c
  *
  * Copyright (c) 2013  LG Electronics,  Namhyung Kim <namhyung@kernel.org>
+ * Copyright (c) 2020  Changbin Du <changbin.du@gmail.com>, significant enhancement.
  */
 
 #include "builtin.h"
@@ -26,6 +27,8 @@
 #include "thread_map.h"
 #include "util/cap.h"
 #include "util/config.h"
+#include "util/units.h"
+#include "util/parse-sublevel-options.h"
 
 #define DEFAULT_TRACER  "function_graph"
 
@@ -33,11 +36,21 @@ struct perf_ftrace {
        struct evlist           *evlist;
        struct target           target;
        const char              *tracer;
+       bool                    list_avail_functions;
        struct list_head        filters;
        struct list_head        notrace;
        struct list_head        graph_funcs;
        struct list_head        nograph_funcs;
        int                     graph_depth;
+       unsigned long           percpu_buffer_size;
+       bool                    inherit;
+       int                     func_stack_trace;
+       int                     func_irq_info;
+       int                     graph_nosleep_time;
+       int                     graph_noirqs;
+       int                     graph_verbose;
+       int                     graph_thresh;
+       unsigned int            initial_delay;
 };
 
 struct filter_entry {
@@ -128,9 +141,85 @@ static int append_tracing_file(const char *name, const char *val)
        return __write_tracing_file(name, val, true);
 }
 
+static int read_tracing_file_to_stdout(const char *name)
+{
+       char buf[4096];
+       char *file;
+       int fd;
+       int ret = -1;
+
+       file = get_tracing_file(name);
+       if (!file) {
+               pr_debug("cannot get tracing file: %s\n", name);
+               return -1;
+       }
+
+       fd = open(file, O_RDONLY);
+       if (fd < 0) {
+               pr_debug("cannot open tracing file: %s: %s\n",
+                        name, str_error_r(errno, buf, sizeof(buf)));
+               goto out;
+       }
+
+       /* read contents to stdout */
+       while (true) {
+               int n = read(fd, buf, sizeof(buf));
+               if (n == 0)
+                       break;
+               else if (n < 0)
+                       goto out_close;
+
+               if (fwrite(buf, n, 1, stdout) != 1)
+                       goto out_close;
+       }
+       ret = 0;
+
+out_close:
+       close(fd);
+out:
+       put_tracing_file(file);
+       return ret;
+}
+
+static int write_tracing_file_int(const char *name, int value)
+{
+       char buf[16];
+
+       snprintf(buf, sizeof(buf), "%d", value);
+       if (write_tracing_file(name, buf) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int write_tracing_option_file(const char *name, const char *val)
+{
+       char *file;
+       int ret;
+
+       if (asprintf(&file, "options/%s", name) < 0)
+               return -1;
+
+       ret = __write_tracing_file(file, val, false);
+       free(file);
+       return ret;
+}
+
 static int reset_tracing_cpu(void);
 static void reset_tracing_filters(void);
 
+static void reset_tracing_options(struct perf_ftrace *ftrace __maybe_unused)
+{
+       write_tracing_option_file("function-fork", "0");
+       write_tracing_option_file("func_stack_trace", "0");
+       write_tracing_option_file("sleep-time", "1");
+       write_tracing_option_file("funcgraph-irqs", "1");
+       write_tracing_option_file("funcgraph-proc", "0");
+       write_tracing_option_file("funcgraph-abstime", "0");
+       write_tracing_option_file("latency-format", "0");
+       write_tracing_option_file("irq-info", "0");
+}
+
 static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
 {
        if (write_tracing_file("tracing_on", "0") < 0)
@@ -148,7 +237,11 @@ static int reset_tracing_files(struct perf_ftrace *ftrace __maybe_unused)
        if (write_tracing_file("max_graph_depth", "0") < 0)
                return -1;
 
+       if (write_tracing_file("tracing_thresh", "0") < 0)
+               return -1;
+
        reset_tracing_filters();
+       reset_tracing_options(ftrace);
        return 0;
 }
 
@@ -204,6 +297,28 @@ static int set_tracing_cpu(struct perf_ftrace *ftrace)
        return set_tracing_cpumask(cpumap);
 }
 
+static int set_tracing_func_stack_trace(struct perf_ftrace *ftrace)
+{
+       if (!ftrace->func_stack_trace)
+               return 0;
+
+       if (write_tracing_option_file("func_stack_trace", "1") < 0)
+               return -1;
+
+       return 0;
+}
+
+static int set_tracing_func_irqinfo(struct perf_ftrace *ftrace)
+{
+       if (!ftrace->func_irq_info)
+               return 0;
+
+       if (write_tracing_option_file("irq-info", "1") < 0)
+               return -1;
+
+       return 0;
+}
+
 static int reset_tracing_cpu(void)
 {
        struct perf_cpu_map *cpumap = perf_cpu_map__new(NULL);
@@ -258,8 +373,6 @@ static void reset_tracing_filters(void)
 
 static int set_tracing_depth(struct perf_ftrace *ftrace)
 {
-       char buf[16];
-
        if (ftrace->graph_depth == 0)
                return 0;
 
@@ -268,10 +381,152 @@ static int set_tracing_depth(struct perf_ftrace *ftrace)
                return -1;
        }
 
-       snprintf(buf, sizeof(buf), "%d", ftrace->graph_depth);
+       if (write_tracing_file_int("max_graph_depth", ftrace->graph_depth) < 0)
+               return -1;
+
+       return 0;
+}
+
+static int set_tracing_percpu_buffer_size(struct perf_ftrace *ftrace)
+{
+       int ret;
+
+       if (ftrace->percpu_buffer_size == 0)
+               return 0;
+
+       ret = write_tracing_file_int("buffer_size_kb",
+                                    ftrace->percpu_buffer_size / 1024);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int set_tracing_trace_inherit(struct perf_ftrace *ftrace)
+{
+       if (!ftrace->inherit)
+               return 0;
+
+       if (write_tracing_option_file("function-fork", "1") < 0)
+               return -1;
+
+       return 0;
+}
+
+static int set_tracing_sleep_time(struct perf_ftrace *ftrace)
+{
+       if (!ftrace->graph_nosleep_time)
+               return 0;
+
+       if (write_tracing_option_file("sleep-time", "0") < 0)
+               return -1;
+
+       return 0;
+}
+
+static int set_tracing_funcgraph_irqs(struct perf_ftrace *ftrace)
+{
+       if (!ftrace->graph_noirqs)
+               return 0;
+
+       if (write_tracing_option_file("funcgraph-irqs", "0") < 0)
+               return -1;
+
+       return 0;
+}
+
+static int set_tracing_funcgraph_verbose(struct perf_ftrace *ftrace)
+{
+       if (!ftrace->graph_verbose)
+               return 0;
+
+       if (write_tracing_option_file("funcgraph-proc", "1") < 0)
+               return -1;
+
+       if (write_tracing_option_file("funcgraph-abstime", "1") < 0)
+               return -1;
+
+       if (write_tracing_option_file("latency-format", "1") < 0)
+               return -1;
+
+       return 0;
+}
+
+static int set_tracing_thresh(struct perf_ftrace *ftrace)
+{
+       int ret;
+
+       if (ftrace->graph_thresh == 0)
+               return 0;
+
+       ret = write_tracing_file_int("tracing_thresh", ftrace->graph_thresh);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int set_tracing_options(struct perf_ftrace *ftrace)
+{
+       if (set_tracing_pid(ftrace) < 0) {
+               pr_err("failed to set ftrace pid\n");
+               return -1;
+       }
+
+       if (set_tracing_cpu(ftrace) < 0) {
+               pr_err("failed to set tracing cpumask\n");
+               return -1;
+       }
+
+       if (set_tracing_func_stack_trace(ftrace) < 0) {
+               pr_err("failed to set tracing option func_stack_trace\n");
+               return -1;
+       }
+
+       if (set_tracing_func_irqinfo(ftrace) < 0) {
+               pr_err("failed to set tracing option irq-info\n");
+               return -1;
+       }
+
+       if (set_tracing_filters(ftrace) < 0) {
+               pr_err("failed to set tracing filters\n");
+               return -1;
+       }
+
+       if (set_tracing_depth(ftrace) < 0) {
+               pr_err("failed to set graph depth\n");
+               return -1;
+       }
+
+       if (set_tracing_percpu_buffer_size(ftrace) < 0) {
+               pr_err("failed to set tracing per-cpu buffer size\n");
+               return -1;
+       }
+
+       if (set_tracing_trace_inherit(ftrace) < 0) {
+               pr_err("failed to set tracing option function-fork\n");
+               return -1;
+       }
+
+       if (set_tracing_sleep_time(ftrace) < 0) {
+               pr_err("failed to set tracing option sleep-time\n");
+               return -1;
+       }
+
+       if (set_tracing_funcgraph_irqs(ftrace) < 0) {
+               pr_err("failed to set tracing option funcgraph-irqs\n");
+               return -1;
+       }
 
-       if (write_tracing_file("max_graph_depth", buf) < 0)
+       if (set_tracing_funcgraph_verbose(ftrace) < 0) {
+               pr_err("failed to set tracing option funcgraph-proc/funcgraph-abstime\n");
                return -1;
+       }
+
+       if (set_tracing_thresh(ftrace) < 0) {
+               pr_err("failed to set tracing thresh\n");
+               return -1;
+       }
 
        return 0;
 }
@@ -302,6 +557,9 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
        signal(SIGCHLD, sig_handler);
        signal(SIGPIPE, sig_handler);
 
+       if (ftrace->list_avail_functions)
+               return read_tracing_file_to_stdout("available_filter_functions");
+
        if (reset_tracing_files(ftrace) < 0) {
                pr_err("failed to reset ftrace\n");
                goto out;
@@ -317,25 +575,8 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
                goto out;
        }
 
-       if (set_tracing_pid(ftrace) < 0) {
-               pr_err("failed to set ftrace pid\n");
+       if (set_tracing_options(ftrace) < 0)
                goto out_reset;
-       }
-
-       if (set_tracing_cpu(ftrace) < 0) {
-               pr_err("failed to set tracing cpumask\n");
-               goto out_reset;
-       }
-
-       if (set_tracing_filters(ftrace) < 0) {
-               pr_err("failed to set tracing filters\n");
-               goto out_reset;
-       }
-
-       if (set_tracing_depth(ftrace) < 0) {
-               pr_err("failed to set graph depth\n");
-               goto out_reset;
-       }
 
        if (write_tracing_file("current_tracer", ftrace->tracer) < 0) {
                pr_err("failed to set current_tracer to %s\n", ftrace->tracer);
@@ -362,13 +603,26 @@ static int __cmd_ftrace(struct perf_ftrace *ftrace, int argc, const char **argv)
        fcntl(trace_fd, F_SETFL, O_NONBLOCK);
        pollfd.fd = trace_fd;
 
-       if (write_tracing_file("tracing_on", "1") < 0) {
-               pr_err("can't enable tracing\n");
-               goto out_close_fd;
+       /* display column headers */
+       read_tracing_file_to_stdout("trace");
+
+       if (!ftrace->initial_delay) {
+               if (write_tracing_file("tracing_on", "1") < 0) {
+                       pr_err("can't enable tracing\n");
+                       goto out_close_fd;
+               }
        }
 
        perf_evlist__start_workload(ftrace->evlist);
 
+       if (ftrace->initial_delay) {
+               usleep(ftrace->initial_delay * 1000);
+               if (write_tracing_file("tracing_on", "1") < 0) {
+                       pr_err("can't enable tracing\n");
+                       goto out_close_fd;
+               }
+       }
+
        while (!done) {
                if (poll(&pollfd, 1, -1) < 0)
                        break;
@@ -455,6 +709,99 @@ static void delete_filter_func(struct list_head *head)
        }
 }
 
+static int parse_buffer_size(const struct option *opt,
+                            const char *str, int unset)
+{
+       unsigned long *s = (unsigned long *)opt->value;
+       static struct parse_tag tags_size[] = {
+               { .tag  = 'B', .mult = 1       },
+               { .tag  = 'K', .mult = 1 << 10 },
+               { .tag  = 'M', .mult = 1 << 20 },
+               { .tag  = 'G', .mult = 1 << 30 },
+               { .tag  = 0 },
+       };
+       unsigned long val;
+
+       if (unset) {
+               *s = 0;
+               return 0;
+       }
+
+       val = parse_tag_value(str, tags_size);
+       if (val != (unsigned long) -1) {
+               if (val < 1024) {
+                       pr_err("buffer size too small, must larger than 1KB.");
+                       return -1;
+               }
+               *s = val;
+               return 0;
+       }
+
+       return -1;
+}
+
+static int parse_func_tracer_opts(const struct option *opt,
+                                 const char *str, int unset)
+{
+       int ret;
+       struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value;
+       struct sublevel_option func_tracer_opts[] = {
+               { .name = "call-graph", .value_ptr = &ftrace->func_stack_trace },
+               { .name = "irq-info",   .value_ptr = &ftrace->func_irq_info },
+               { .name = NULL, }
+       };
+
+       if (unset)
+               return 0;
+
+       ret = perf_parse_sublevel_options(str, func_tracer_opts);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int parse_graph_tracer_opts(const struct option *opt,
+                                 const char *str, int unset)
+{
+       int ret;
+       struct perf_ftrace *ftrace = (struct perf_ftrace *) opt->value;
+       struct sublevel_option graph_tracer_opts[] = {
+               { .name = "nosleep-time",       .value_ptr = &ftrace->graph_nosleep_time },
+               { .name = "noirqs",             .value_ptr = &ftrace->graph_noirqs },
+               { .name = "verbose",            .value_ptr = &ftrace->graph_verbose },
+               { .name = "thresh",             .value_ptr = &ftrace->graph_thresh },
+               { .name = "depth",              .value_ptr = &ftrace->graph_depth },
+               { .name = NULL, }
+       };
+
+       if (unset)
+               return 0;
+
+       ret = perf_parse_sublevel_options(str, graph_tracer_opts);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static void select_tracer(struct perf_ftrace *ftrace)
+{
+       bool graph = !list_empty(&ftrace->graph_funcs) ||
+                    !list_empty(&ftrace->nograph_funcs);
+       bool func = !list_empty(&ftrace->filters) ||
+                   !list_empty(&ftrace->notrace);
+
+       /* The function_graph has priority over function tracer. */
+       if (graph)
+               ftrace->tracer = "function_graph";
+       else if (func)
+               ftrace->tracer = "function";
+       /* Otherwise, the default tracer is used. */
+
+       pr_debug("%s tracer is used\n", ftrace->tracer);
+}
+
 int cmd_ftrace(int argc, const char **argv)
 {
        int ret;
@@ -469,25 +816,42 @@ int cmd_ftrace(int argc, const char **argv)
        };
        const struct option ftrace_options[] = {
        OPT_STRING('t', "tracer", &ftrace.tracer, "tracer",
-                  "tracer to use: function_graph(default) or function"),
+                  "Tracer to use: function_graph(default) or function"),
+       OPT_BOOLEAN('F', "funcs", &ftrace.list_avail_functions,
+                   "Show available functions to filter"),
        OPT_STRING('p', "pid", &ftrace.target.pid, "pid",
-                  "trace on existing process id"),
+                  "Trace on existing process id"),
+       /* TODO: Add short option -t after -t/--tracer can be removed. */
+       OPT_STRING(0, "tid", &ftrace.target.tid, "tid",
+                  "Trace on existing thread id (exclusive to --pid)"),
        OPT_INCR('v', "verbose", &verbose,
-                "be more verbose"),
+                "Be more verbose"),
        OPT_BOOLEAN('a', "all-cpus", &ftrace.target.system_wide,
-                   "system-wide collection from all CPUs"),
+                   "System-wide collection from all CPUs"),
        OPT_STRING('C', "cpu", &ftrace.target.cpu_list, "cpu",
-                   "list of cpus to monitor"),
+                   "List of cpus to monitor"),
        OPT_CALLBACK('T', "trace-funcs", &ftrace.filters, "func",
-                    "trace given functions only", parse_filter_func),
+                    "Trace given functions using function tracer",
+                    parse_filter_func),
        OPT_CALLBACK('N', "notrace-funcs", &ftrace.notrace, "func",
-                    "do not trace given functions", parse_filter_func),
+                    "Do not trace given functions", parse_filter_func),
+       OPT_CALLBACK(0, "func-opts", &ftrace, "options",
+                    "Function tracer options, available options: call-graph,irq-info",
+                    parse_func_tracer_opts),
        OPT_CALLBACK('G', "graph-funcs", &ftrace.graph_funcs, "func",
-                    "Set graph filter on given functions", parse_filter_func),
+                    "Trace given functions using function_graph tracer",
+                    parse_filter_func),
        OPT_CALLBACK('g', "nograph-funcs", &ftrace.nograph_funcs, "func",
                     "Set nograph filter on given functions", parse_filter_func),
-       OPT_INTEGER('D', "graph-depth", &ftrace.graph_depth,
-                   "Max depth for function graph tracer"),
+       OPT_CALLBACK(0, "graph-opts", &ftrace, "options",
+                    "Graph tracer options, available options: nosleep-time,noirqs,verbose,thresh=<n>,depth=<n>",
+                    parse_graph_tracer_opts),
+       OPT_CALLBACK('m', "buffer-size", &ftrace.percpu_buffer_size, "size",
+                    "Size of per cpu buffer, needs to use a B, K, M or G suffix.", parse_buffer_size),
+       OPT_BOOLEAN(0, "inherit", &ftrace.inherit,
+                   "Trace children processes"),
+       OPT_UINTEGER('D', "delay", &ftrace.initial_delay,
+                    "Number of milliseconds to wait before starting tracing after program start"),
        OPT_END()
        };
 
@@ -505,6 +869,8 @@ int cmd_ftrace(int argc, const char **argv)
        if (!argc && target__none(&ftrace.target))
                ftrace.target.system_wide = true;
 
+       select_tracer(&ftrace);
+
        ret = target__validate(&ftrace.target);
        if (ret) {
                char errbuf[512];
index 459e422..0c7d599 100644 (file)
@@ -2398,6 +2398,15 @@ static void timehist_print_wakeup_event(struct perf_sched *sched,
        printf("\n");
 }
 
+static int timehist_sched_wakeup_ignore(struct perf_tool *tool __maybe_unused,
+                                       union perf_event *event __maybe_unused,
+                                       struct evsel *evsel __maybe_unused,
+                                       struct perf_sample *sample __maybe_unused,
+                                       struct machine *machine __maybe_unused)
+{
+       return 0;
+}
+
 static int timehist_sched_wakeup_event(struct perf_tool *tool,
                                       union perf_event *event __maybe_unused,
                                       struct evsel *evsel,
@@ -2958,9 +2967,10 @@ static int timehist_check_attr(struct perf_sched *sched,
 
 static int perf_sched__timehist(struct perf_sched *sched)
 {
-       const struct evsel_str_handler handlers[] = {
+       struct evsel_str_handler handlers[] = {
                { "sched:sched_switch",       timehist_sched_switch_event, },
                { "sched:sched_wakeup",       timehist_sched_wakeup_event, },
+               { "sched:sched_waking",       timehist_sched_wakeup_event, },
                { "sched:sched_wakeup_new",   timehist_sched_wakeup_event, },
        };
        const struct evsel_str_handler migrate_handlers[] = {
@@ -3018,6 +3028,11 @@ static int perf_sched__timehist(struct perf_sched *sched)
 
        setup_pager();
 
+       /* prefer sched_waking if it is captured */
+       if (perf_evlist__find_tracepoint_by_name(session->evlist,
+                                                 "sched:sched_waking"))
+               handlers[1].handler = timehist_sched_wakeup_ignore;
+
        /* setup per-evsel handlers */
        if (perf_session__set_tracepoints_handlers(session, handlers))
                goto out;
@@ -3330,12 +3345,16 @@ static int __cmd_record(int argc, const char **argv)
                "-e", "sched:sched_stat_iowait",
                "-e", "sched:sched_stat_runtime",
                "-e", "sched:sched_process_fork",
-               "-e", "sched:sched_wakeup",
                "-e", "sched:sched_wakeup_new",
                "-e", "sched:sched_migrate_task",
        };
+       struct tep_event *waking_event;
 
-       rec_argc = ARRAY_SIZE(record_args) + argc - 1;
+       /*
+        * +2 for either "-e", "sched:sched_wakeup" or
+        * "-e", "sched:sched_waking"
+        */
+       rec_argc = ARRAY_SIZE(record_args) + 2 + argc - 1;
        rec_argv = calloc(rec_argc + 1, sizeof(char *));
 
        if (rec_argv == NULL)
@@ -3344,6 +3363,13 @@ static int __cmd_record(int argc, const char **argv)
        for (i = 0; i < ARRAY_SIZE(record_args); i++)
                rec_argv[i] = strdup(record_args[i]);
 
+       rec_argv[i++] = "-e";
+       waking_event = trace_event__tp_format("sched", "sched_waking");
+       if (!IS_ERR(waking_event))
+               rec_argv[i++] = strdup("sched:sched_waking");
+       else
+               rec_argv[i++] = strdup("sched:sched_wakeup");
+
        for (j = 1; j < (unsigned int)argc; j++, i++)
                rec_argv[i] = argv[j];
 
index 94c2bc2..0b4d643 100755 (executable)
@@ -128,6 +128,9 @@ check arch/x86/lib/insn.c             '-I "^#include [\"<]\(../include/\)*asm/in
 # diff non-symmetric files
 check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl
 
+# These will require a beauty_check when we get some more like that
+check_2 tools/perf/trace/beauty/include/linux/socket.h include/linux/socket.h
+
 # check duplicated library files
 check_2 tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h
 check_2 tools/perf/util/hashmap.c tools/lib/bpf/hashmap.c
index 80816d6..f8784c6 100644 (file)
@@ -60,7 +60,7 @@
     },
     {
         "BriefDescription": "Stalls due to short latency decimal floating ops.",
-        "MetricExpr": "(PM_CMPLU_STALL_DFU - PM_CMPLU_STALL_DFLONG)/PM_RUN_INST_CMPL",
+        "MetricExpr": "dfu_stall_cpi - dflong_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "dfu_other_stall_cpi"
     },
@@ -72,7 +72,7 @@
     },
     {
         "BriefDescription": "Completion stall by Dcache miss which resolved off node memory/cache",
-        "MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM - PM_CMPLU_STALL_DMISS_REMOTE)/PM_RUN_INST_CMPL",
+        "MetricExpr": "dmiss_non_local_stall_cpi - dmiss_remote_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "dmiss_distant_stall_cpi"
     },
@@ -90,7 +90,7 @@
     },
     {
         "BriefDescription": "Completion stall due to cache miss that resolves in the L2 or L3 without conflict",
-        "MetricExpr": "(PM_CMPLU_STALL_DMISS_L2L3 - PM_CMPLU_STALL_DMISS_L2L3_CONFLICT)/PM_RUN_INST_CMPL",
+        "MetricExpr": "dmiss_l2l3_stall_cpi - dmiss_l2l3_conflict_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "dmiss_l2l3_noconflict_stall_cpi"
     },
     },
     {
         "BriefDescription": "Completion stall by Dcache miss which resolved outside of local memory",
-        "MetricExpr": "(PM_CMPLU_STALL_DMISS_L3MISS - PM_CMPLU_STALL_DMISS_L21_L31 - PM_CMPLU_STALL_DMISS_LMEM)/PM_RUN_INST_CMPL",
+        "MetricExpr": "dmiss_l3miss_stall_cpi - dmiss_l21_l31_stall_cpi - dmiss_lmem_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "dmiss_non_local_stall_cpi"
     },
     },
     {
         "BriefDescription": "Stalls due to short latency double precision ops.",
-        "MetricExpr": "(PM_CMPLU_STALL_DP - PM_CMPLU_STALL_DPLONG)/PM_RUN_INST_CMPL",
+        "MetricExpr": "dp_stall_cpi - dplong_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "dp_other_stall_cpi"
     },
         "MetricName": "emq_full_stall_cpi"
     },
     {
-        "MetricExpr": "(PM_CMPLU_STALL_ERAT_MISS + PM_CMPLU_STALL_EMQ_FULL)/PM_RUN_INST_CMPL",
+        "MetricExpr": "erat_miss_stall_cpi + emq_full_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "emq_stall_cpi"
     },
     },
     {
         "BriefDescription": "Completion stall due to execution units for other reasons.",
-        "MetricExpr": "(PM_CMPLU_STALL_EXEC_UNIT - PM_CMPLU_STALL_FXU - PM_CMPLU_STALL_DP - PM_CMPLU_STALL_DFU - PM_CMPLU_STALL_PM - PM_CMPLU_STALL_CRYPTO - PM_CMPLU_STALL_VFXU - PM_CMPLU_STALL_VDP)/PM_RUN_INST_CMPL",
+        "MetricExpr": "exec_unit_stall_cpi - scalar_stall_cpi - vector_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "exec_unit_other_stall_cpi"
     },
     },
     {
         "BriefDescription": "Stalls due to short latency integer ops",
-        "MetricExpr": "(PM_CMPLU_STALL_FXU - PM_CMPLU_STALL_FXLONG)/PM_RUN_INST_CMPL",
+        "MetricExpr": "fxu_stall_cpi - fxlong_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "fxu_other_stall_cpi"
     },
     },
     {
         "BriefDescription": "Instruction Completion Table other stalls",
-        "MetricExpr": "(PM_ICT_NOSLOT_CYC - PM_ICT_NOSLOT_IC_MISS - PM_ICT_NOSLOT_BR_MPRED_ICMISS - PM_ICT_NOSLOT_BR_MPRED - PM_ICT_NOSLOT_DISP_HELD)/PM_RUN_INST_CMPL",
+        "MetricExpr": "nothing_dispatched_cpi - ict_noslot_ic_miss_cpi - ict_noslot_br_mpred_icmiss_cpi - ict_noslot_br_mpred_cpi - ict_noslot_disp_held_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "ict_noslot_cyc_other_cpi"
     },
     },
     {
         "BriefDescription": "ICT_NOSLOT_DISP_HELD_OTHER_CPI",
-        "MetricExpr": "(PM_ICT_NOSLOT_DISP_HELD - PM_ICT_NOSLOT_DISP_HELD_HB_FULL - PM_ICT_NOSLOT_DISP_HELD_SYNC - PM_ICT_NOSLOT_DISP_HELD_TBEGIN - PM_ICT_NOSLOT_DISP_HELD_ISSQ)/PM_RUN_INST_CMPL",
+        "MetricExpr": "ict_noslot_disp_held_cpi - ict_noslot_disp_held_hb_full_cpi - ict_noslot_disp_held_sync_cpi - ict_noslot_disp_held_tbegin_cpi - ict_noslot_disp_held_issq_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "ict_noslot_disp_held_other_cpi"
     },
     },
     {
         "BriefDescription": "ICT_NOSLOT_IC_L2_CPI",
-        "MetricExpr": "(PM_ICT_NOSLOT_IC_MISS - PM_ICT_NOSLOT_IC_L3 - PM_ICT_NOSLOT_IC_L3MISS)/PM_RUN_INST_CMPL",
+        "MetricExpr": "ict_noslot_ic_miss_cpi - ict_noslot_ic_l3_cpi - ict_noslot_ic_l3miss_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "ict_noslot_ic_l2_cpi"
     },
         "MetricName": "ict_noslot_ic_miss_cpi"
     },
     {
-        "MetricExpr": "(PM_NTC_ISSUE_HELD_DARQ_FULL + PM_NTC_ISSUE_HELD_ARB + PM_NTC_ISSUE_HELD_OTHER)/PM_RUN_INST_CMPL",
+        "MetricExpr": "ntc_issue_held_darq_full_cpi + ntc_issue_held_arb_cpi + ntc_issue_held_other_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "issue_hold_cpi"
     },
         "MetricName": "lrq_other_stall_cpi"
     },
     {
-        "MetricExpr": "(PM_CMPLU_STALL_LMQ_FULL + PM_CMPLU_STALL_ST_FWD + PM_CMPLU_STALL_LHS + PM_CMPLU_STALL_LSU_MFSPR + PM_CMPLU_STALL_LARX + PM_CMPLU_STALL_LRQ_OTHER)/PM_RUN_INST_CMPL",
+        "MetricExpr": "lmq_full_stall_cpi + st_fwd_stall_cpi + lhs_stall_cpi + lsu_mfspr_stall_cpi + larx_stall_cpi + lrq_other_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "lrq_stall_cpi"
     },
         "MetricName": "lsaq_arb_stall_cpi"
     },
     {
-        "MetricExpr": "(PM_CMPLU_STALL_LRQ_FULL + PM_CMPLU_STALL_SRQ_FULL + PM_CMPLU_STALL_LSAQ_ARB)/PM_RUN_INST_CMPL",
+        "MetricExpr": "lrq_full_stall_cpi + srq_full_stall_cpi + lsaq_arb_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "lsaq_stall_cpi"
     },
     },
     {
         "BriefDescription": "Completion LSU stall for other reasons",
-        "MetricExpr": "(PM_CMPLU_STALL_LSU - PM_CMPLU_STALL_LSU_FIN - PM_CMPLU_STALL_STORE_FINISH - PM_CMPLU_STALL_STORE_DATA - PM_CMPLU_STALL_EIEIO - PM_CMPLU_STALL_STCX - PM_CMPLU_STALL_SLB - PM_CMPLU_STALL_TEND - PM_CMPLU_STALL_PASTE - PM_CMPLU_STALL_TLBIE - PM_CMPLU_STALL_STORE_PIPE_ARB - PM_CMPLU_STALL_STORE_FIN_ARB - PM_CMPLU_STALL_LOAD_FINISH + PM_CMPLU_STALL_DCACHE_MISS - PM_CMPLU_STALL_LMQ_FULL - PM_CMPLU_STALL_ST_FWD - PM_CMPLU_STALL_LHS - PM_CMPLU_STALL_LSU_MFSPR - PM_CMPLU_STALL_LARX - PM_CMPLU_STALL_LRQ_OTHER + PM_CMPLU_STALL_ERAT_MISS + PM_CMPLU_STALL_EMQ_FULL - PM_CMPLU_STALL_LRQ_FULL - PM_CMPLU_STALL_SRQ_FULL - PM_CMPLU_STALL_LSAQ_ARB) / PM_RUN_INST_CMPL",
+        "MetricExpr": "lsu_stall_cpi - lsu_fin_stall_cpi - store_finish_stall_cpi - srq_stall_cpi - load_finish_stall_cpi + lsu_stall_dcache_miss_cpi - lrq_stall_cpi + emq_stall_cpi - lsaq_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "lsu_other_stall_cpi"
     },
     },
     {
         "BriefDescription": "Cycles unaccounted for.",
-        "MetricExpr": "(PM_RUN_CYC - PM_1PLUS_PPC_CMPL - PM_CMPLU_STALL_THRD - PM_CMPLU_STALL - PM_ICT_NOSLOT_CYC)/PM_RUN_INST_CMPL",
+        "MetricExpr": "run_cpi - completion_cpi - thread_block_stall_cpi - stall_cpi - nothing_dispatched_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "other_cpi"
     },
     {
         "BriefDescription": "Completion stall for other reasons",
-        "MetricExpr": "(PM_CMPLU_STALL - PM_CMPLU_STALL_NTC_DISP_FIN - PM_CMPLU_STALL_NTC_FLUSH - PM_CMPLU_STALL_LSU - PM_CMPLU_STALL_EXEC_UNIT - PM_CMPLU_STALL_BRU)/PM_RUN_INST_CMPL",
+        "MetricExpr": "stall_cpi - ntc_disp_fin_stall_cpi - ntc_flush_stall_cpi - lsu_stall_cpi - exec_unit_stall_cpi - bru_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "other_stall_cpi"
     },
         "MetricName": "run_cyc_cpi"
     },
     {
-        "MetricExpr": "(PM_CMPLU_STALL_FXU + PM_CMPLU_STALL_DP + PM_CMPLU_STALL_DFU + PM_CMPLU_STALL_PM + PM_CMPLU_STALL_CRYPTO)/PM_RUN_INST_CMPL",
+        "MetricExpr": "fxu_stall_cpi + dp_stall_cpi + dfu_stall_cpi + pm_stall_cpi + crypto_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "scalar_stall_cpi"
     },
         "MetricName": "srq_full_stall_cpi"
     },
     {
-        "MetricExpr": "(PM_CMPLU_STALL_STORE_DATA + PM_CMPLU_STALL_EIEIO + PM_CMPLU_STALL_STCX + PM_CMPLU_STALL_SLB + PM_CMPLU_STALL_TEND + PM_CMPLU_STALL_PASTE + PM_CMPLU_STALL_TLBIE + PM_CMPLU_STALL_STORE_PIPE_ARB + PM_CMPLU_STALL_STORE_FIN_ARB)/PM_RUN_INST_CMPL",
+        "MetricExpr": "store_data_stall_cpi + eieio_stall_cpi + stcx_stall_cpi + slb_stall_cpi + tend_stall_cpi + paste_stall_cpi + tlbie_stall_cpi + store_pipe_arb_stall_cpi + store_fin_arb_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "srq_stall_cpi"
     },
     },
     {
         "BriefDescription": "Vector stalls due to small latency double precision ops",
-        "MetricExpr": "(PM_CMPLU_STALL_VDP - PM_CMPLU_STALL_VDPLONG)/PM_RUN_INST_CMPL",
+        "MetricExpr": "vdp_stall_cpi - vdplong_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "vdp_other_stall_cpi"
     },
         "MetricName": "vdplong_stall_cpi"
     },
     {
-        "MetricExpr": "(PM_CMPLU_STALL_VFXU + PM_CMPLU_STALL_VDP)/PM_RUN_INST_CMPL",
+        "MetricExpr": "vfxu_stall_cpi + vdp_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "vector_stall_cpi"
     },
     },
     {
         "BriefDescription": "Vector stalls due to small latency integer ops",
-        "MetricExpr": "(PM_CMPLU_STALL_VFXU - PM_CMPLU_STALL_VFXLONG)/PM_RUN_INST_CMPL",
+        "MetricExpr": "vfxu_stall_cpi - vfxlong_stall_cpi",
         "MetricGroup": "cpi_breakdown",
         "MetricName": "vfxu_other_stall_cpi"
     },
     },
     {
         "BriefDescription": "% of DL1 reloads from Private L3, other core per Inst",
-        "MetricExpr": "(PM_DATA_FROM_L31_MOD + PM_DATA_FROM_L31_SHR) * 100 / PM_RUN_INST_CMPL",
+        "MetricExpr": "dl1_reload_from_l31_mod_rate_percent + dl1_reload_from_l31_shr_rate_percent",
         "MetricName": "dl1_reload_from_l31_rate_percent"
     },
     {
     },
     {
         "BriefDescription": "Completion stall because a different thread was using the completion pipe",
-        "MetricExpr": "(PM_CMPLU_STALL_THRD - PM_CMPLU_STALL_EXCEPTION - PM_CMPLU_STALL_ANY_SYNC - PM_CMPLU_STALL_SYNC_PMU_INT - PM_CMPLU_STALL_SPEC_FINISH - PM_CMPLU_STALL_FLUSH_ANY_THREAD - PM_CMPLU_STALL_LSU_FLUSH_NEXT - PM_CMPLU_STALL_NESTED_TBEGIN - PM_CMPLU_STALL_NESTED_TEND - PM_CMPLU_STALL_MTFPSCR)/PM_RUN_INST_CMPL",
+        "MetricExpr": "thread_block_stall_cpi - exception_stall_cpi - any_sync_stall_cpi - sync_pmu_int_stall_cpi - spec_finish_stall_cpi - flush_any_thread_stall_cpi - lsu_flush_next_stall_cpi - nested_tbegin_stall_cpi - nested_tend_stall_cpi - mtfpscr_stall_cpi",
         "MetricName": "other_thread_cmpl_stall"
     },
     {
index 54030c1..bf9e729 100755 (executable)
@@ -20,13 +20,13 @@ file=$(mktemp /tmp/temporary_file.XXXXX)
 
 record_open_file() {
        echo "Recording open file:"
-       perf record -o ${perfdata} -e probe:vfs_getname touch $file
+       perf record -o ${perfdata} -e probe:vfs_getname\* touch $file
 }
 
 perf_script_filenames() {
        echo "Looking at perf.data file for vfs_getname records for the file we touched:"
        perf script -i ${perfdata} | \
-       egrep " +touch +[0-9]+ +\[[0-9]+\] +[0-9]+\.[0-9]+: +probe:vfs_getname: +\([[:xdigit:]]+\) +pathname=\"${file}\""
+       egrep " +touch +[0-9]+ +\[[0-9]+\] +[0-9]+\.[0-9]+: +probe:vfs_getname[_0-9]*: +\([[:xdigit:]]+\) +pathname=\"${file}\""
 }
 
 add_probe_vfs_getname || skip_if_no_debuginfo
diff --git a/tools/perf/trace/beauty/include/linux/socket.h b/tools/perf/trace/beauty/include/linux/socket.h
new file mode 100644 (file)
index 0000000..e9cb30d
--- /dev/null
@@ -0,0 +1,442 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_SOCKET_H
+#define _LINUX_SOCKET_H
+
+
+#include <asm/socket.h>                        /* arch-dependent defines       */
+#include <linux/sockios.h>             /* the SIOCxxx I/O controls     */
+#include <linux/uio.h>                 /* iovec support                */
+#include <linux/types.h>               /* pid_t                        */
+#include <linux/compiler.h>            /* __user                       */
+#include <uapi/linux/socket.h>
+
+struct file;
+struct pid;
+struct cred;
+struct socket;
+
+#define __sockaddr_check_size(size)    \
+       BUILD_BUG_ON(((size) > sizeof(struct __kernel_sockaddr_storage)))
+
+#ifdef CONFIG_PROC_FS
+struct seq_file;
+extern void socket_seq_show(struct seq_file *seq);
+#endif
+
+typedef __kernel_sa_family_t   sa_family_t;
+
+/*
+ *     1003.1g requires sa_family_t and that sa_data is char.
+ */
+
+struct sockaddr {
+       sa_family_t     sa_family;      /* address family, AF_xxx       */
+       char            sa_data[14];    /* 14 bytes of protocol address */
+};
+
+struct linger {
+       int             l_onoff;        /* Linger active                */
+       int             l_linger;       /* How long to linger for       */
+};
+
+#define sockaddr_storage __kernel_sockaddr_storage
+
+/*
+ *     As we do 4.4BSD message passing we use a 4.4BSD message passing
+ *     system, not 4.3. Thus msg_accrights(len) are now missing. They
+ *     belong in an obscure libc emulation or the bin.
+ */
+
+struct msghdr {
+       void            *msg_name;      /* ptr to socket address structure */
+       int             msg_namelen;    /* size of socket address structure */
+       struct iov_iter msg_iter;       /* data */
+
+       /*
+        * Ancillary data. msg_control_user is the user buffer used for the
+        * recv* side when msg_control_is_user is set, msg_control is the kernel
+        * buffer used for all other cases.
+        */
+       union {
+               void            *msg_control;
+               void __user     *msg_control_user;
+       };
+       bool            msg_control_is_user : 1;
+       __kernel_size_t msg_controllen; /* ancillary data buffer length */
+       unsigned int    msg_flags;      /* flags on received message */
+       struct kiocb    *msg_iocb;      /* ptr to iocb for async requests */
+};
+
+struct user_msghdr {
+       void            __user *msg_name;       /* ptr to socket address structure */
+       int             msg_namelen;            /* size of socket address structure */
+       struct iovec    __user *msg_iov;        /* scatter/gather array */
+       __kernel_size_t msg_iovlen;             /* # elements in msg_iov */
+       void            __user *msg_control;    /* ancillary data */
+       __kernel_size_t msg_controllen;         /* ancillary data buffer length */
+       unsigned int    msg_flags;              /* flags on received message */
+};
+
+/* For recvmmsg/sendmmsg */
+struct mmsghdr {
+       struct user_msghdr  msg_hdr;
+       unsigned int        msg_len;
+};
+
+/*
+ *     POSIX 1003.1g - ancillary data object information
+ *     Ancillary data consits of a sequence of pairs of
+ *     (cmsghdr, cmsg_data[])
+ */
+
+struct cmsghdr {
+       __kernel_size_t cmsg_len;       /* data byte count, including hdr */
+        int            cmsg_level;     /* originating protocol */
+        int            cmsg_type;      /* protocol-specific type */
+};
+
+/*
+ *     Ancillary data object information MACROS
+ *     Table 5-14 of POSIX 1003.1g
+ */
+
+#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg))
+#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
+
+#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
+
+#define CMSG_DATA(cmsg) \
+       ((void *)(cmsg) + sizeof(struct cmsghdr))
+#define CMSG_USER_DATA(cmsg) \
+       ((void __user *)(cmsg) + sizeof(struct cmsghdr))
+#define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len))
+#define CMSG_LEN(len) (sizeof(struct cmsghdr) + (len))
+
+#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? \
+                                 (struct cmsghdr *)(ctl) : \
+                                 (struct cmsghdr *)NULL)
+#define CMSG_FIRSTHDR(msg)     __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \
+                            (cmsg)->cmsg_len <= (unsigned long) \
+                            ((mhdr)->msg_controllen - \
+                             ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
+#define for_each_cmsghdr(cmsg, msg) \
+       for (cmsg = CMSG_FIRSTHDR(msg); \
+            cmsg; \
+            cmsg = CMSG_NXTHDR(msg, cmsg))
+
+/*
+ *     Get the next cmsg header
+ *
+ *     PLEASE, do not touch this function. If you think, that it is
+ *     incorrect, grep kernel sources and think about consequences
+ *     before trying to improve it.
+ *
+ *     Now it always returns valid, not truncated ancillary object
+ *     HEADER. But caller still MUST check, that cmsg->cmsg_len is
+ *     inside range, given by msg->msg_controllen before using
+ *     ancillary object DATA.                          --ANK (980731)
+ */
+
+static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
+                                              struct cmsghdr *__cmsg)
+{
+       struct cmsghdr * __ptr;
+
+       __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) +  CMSG_ALIGN(__cmsg->cmsg_len));
+       if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
+               return (struct cmsghdr *)0;
+
+       return __ptr;
+}
+
+static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
+{
+       return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
+}
+
+static inline size_t msg_data_left(struct msghdr *msg)
+{
+       return iov_iter_count(&msg->msg_iter);
+}
+
+/* "Socket"-level control message types: */
+
+#define        SCM_RIGHTS      0x01            /* rw: access rights (array of int) */
+#define SCM_CREDENTIALS 0x02           /* rw: struct ucred             */
+#define SCM_SECURITY   0x03            /* rw: security label           */
+
+struct ucred {
+       __u32   pid;
+       __u32   uid;
+       __u32   gid;
+};
+
+/* Supported address families. */
+#define AF_UNSPEC      0
+#define AF_UNIX                1       /* Unix domain sockets          */
+#define AF_LOCAL       1       /* POSIX name for AF_UNIX       */
+#define AF_INET                2       /* Internet IP Protocol         */
+#define AF_AX25                3       /* Amateur Radio AX.25          */
+#define AF_IPX         4       /* Novell IPX                   */
+#define AF_APPLETALK   5       /* AppleTalk DDP                */
+#define AF_NETROM      6       /* Amateur Radio NET/ROM        */
+#define AF_BRIDGE      7       /* Multiprotocol bridge         */
+#define AF_ATMPVC      8       /* ATM PVCs                     */
+#define AF_X25         9       /* Reserved for X.25 project    */
+#define AF_INET6       10      /* IP version 6                 */
+#define AF_ROSE                11      /* Amateur Radio X.25 PLP       */
+#define AF_DECnet      12      /* Reserved for DECnet project  */
+#define AF_NETBEUI     13      /* Reserved for 802.2LLC project*/
+#define AF_SECURITY    14      /* Security callback pseudo AF */
+#define AF_KEY         15      /* PF_KEY key management API */
+#define AF_NETLINK     16
+#define AF_ROUTE       AF_NETLINK /* Alias to emulate 4.4BSD */
+#define AF_PACKET      17      /* Packet family                */
+#define AF_ASH         18      /* Ash                          */
+#define AF_ECONET      19      /* Acorn Econet                 */
+#define AF_ATMSVC      20      /* ATM SVCs                     */
+#define AF_RDS         21      /* RDS sockets                  */
+#define AF_SNA         22      /* Linux SNA Project (nutters!) */
+#define AF_IRDA                23      /* IRDA sockets                 */
+#define AF_PPPOX       24      /* PPPoX sockets                */
+#define AF_WANPIPE     25      /* Wanpipe API Sockets */
+#define AF_LLC         26      /* Linux LLC                    */
+#define AF_IB          27      /* Native InfiniBand address    */
+#define AF_MPLS                28      /* MPLS */
+#define AF_CAN         29      /* Controller Area Network      */
+#define AF_TIPC                30      /* TIPC sockets                 */
+#define AF_BLUETOOTH   31      /* Bluetooth sockets            */
+#define AF_IUCV                32      /* IUCV sockets                 */
+#define AF_RXRPC       33      /* RxRPC sockets                */
+#define AF_ISDN                34      /* mISDN sockets                */
+#define AF_PHONET      35      /* Phonet sockets               */
+#define AF_IEEE802154  36      /* IEEE802154 sockets           */
+#define AF_CAIF                37      /* CAIF sockets                 */
+#define AF_ALG         38      /* Algorithm sockets            */
+#define AF_NFC         39      /* NFC sockets                  */
+#define AF_VSOCK       40      /* vSockets                     */
+#define AF_KCM         41      /* Kernel Connection Multiplexor*/
+#define AF_QIPCRTR     42      /* Qualcomm IPC Router          */
+#define AF_SMC         43      /* smc sockets: reserve number for
+                                * PF_SMC protocol family that
+                                * reuses AF_INET address family
+                                */
+#define AF_XDP         44      /* XDP sockets                  */
+
+#define AF_MAX         45      /* For now.. */
+
+/* Protocol families, same as address families. */
+#define PF_UNSPEC      AF_UNSPEC
+#define PF_UNIX                AF_UNIX
+#define PF_LOCAL       AF_LOCAL
+#define PF_INET                AF_INET
+#define PF_AX25                AF_AX25
+#define PF_IPX         AF_IPX
+#define PF_APPLETALK   AF_APPLETALK
+#define        PF_NETROM       AF_NETROM
+#define PF_BRIDGE      AF_BRIDGE
+#define PF_ATMPVC      AF_ATMPVC
+#define PF_X25         AF_X25
+#define PF_INET6       AF_INET6
+#define PF_ROSE                AF_ROSE
+#define PF_DECnet      AF_DECnet
+#define PF_NETBEUI     AF_NETBEUI
+#define PF_SECURITY    AF_SECURITY
+#define PF_KEY         AF_KEY
+#define PF_NETLINK     AF_NETLINK
+#define PF_ROUTE       AF_ROUTE
+#define PF_PACKET      AF_PACKET
+#define PF_ASH         AF_ASH
+#define PF_ECONET      AF_ECONET
+#define PF_ATMSVC      AF_ATMSVC
+#define PF_RDS         AF_RDS
+#define PF_SNA         AF_SNA
+#define PF_IRDA                AF_IRDA
+#define PF_PPPOX       AF_PPPOX
+#define PF_WANPIPE     AF_WANPIPE
+#define PF_LLC         AF_LLC
+#define PF_IB          AF_IB
+#define PF_MPLS                AF_MPLS
+#define PF_CAN         AF_CAN
+#define PF_TIPC                AF_TIPC
+#define PF_BLUETOOTH   AF_BLUETOOTH
+#define PF_IUCV                AF_IUCV
+#define PF_RXRPC       AF_RXRPC
+#define PF_ISDN                AF_ISDN
+#define PF_PHONET      AF_PHONET
+#define PF_IEEE802154  AF_IEEE802154
+#define PF_CAIF                AF_CAIF
+#define PF_ALG         AF_ALG
+#define PF_NFC         AF_NFC
+#define PF_VSOCK       AF_VSOCK
+#define PF_KCM         AF_KCM
+#define PF_QIPCRTR     AF_QIPCRTR
+#define PF_SMC         AF_SMC
+#define PF_XDP         AF_XDP
+#define PF_MAX         AF_MAX
+
+/* Maximum queue length specifiable by listen.  */
+#define SOMAXCONN      4096
+
+/* Flags we can use with send/ and recv.
+   Added those for 1003.1g not all are supported yet
+ */
+
+#define MSG_OOB                1
+#define MSG_PEEK       2
+#define MSG_DONTROUTE  4
+#define MSG_TRYHARD     4       /* Synonym for MSG_DONTROUTE for DECnet */
+#define MSG_CTRUNC     8
+#define MSG_PROBE      0x10    /* Do not send. Only probe path f.e. for MTU */
+#define MSG_TRUNC      0x20
+#define MSG_DONTWAIT   0x40    /* Nonblocking io                */
+#define MSG_EOR         0x80   /* End of record */
+#define MSG_WAITALL    0x100   /* Wait for a full request */
+#define MSG_FIN         0x200
+#define MSG_SYN                0x400
+#define MSG_CONFIRM    0x800   /* Confirm path validity */
+#define MSG_RST                0x1000
+#define MSG_ERRQUEUE   0x2000  /* Fetch message from error queue */
+#define MSG_NOSIGNAL   0x4000  /* Do not generate SIGPIPE */
+#define MSG_MORE       0x8000  /* Sender will send more */
+#define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */
+#define MSG_SENDPAGE_NOPOLICY 0x10000 /* sendpage() internal : do no apply policy */
+#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
+#define MSG_BATCH      0x40000 /* sendmmsg(): more messages coming */
+#define MSG_EOF         MSG_FIN
+#define MSG_NO_SHARED_FRAGS 0x80000 /* sendpage() internal : page frags are not shared */
+#define MSG_SENDPAGE_DECRYPTED 0x100000 /* sendpage() internal : page may carry
+                                         * plain text and require encryption
+                                         */
+
+#define MSG_ZEROCOPY   0x4000000       /* Use user data in kernel path */
+#define MSG_FASTOPEN   0x20000000      /* Send data in TCP SYN */
+#define MSG_CMSG_CLOEXEC 0x40000000    /* Set close_on_exec for file
+                                          descriptor received through
+                                          SCM_RIGHTS */
+#if defined(CONFIG_COMPAT)
+#define MSG_CMSG_COMPAT        0x80000000      /* This message needs 32 bit fixups */
+#else
+#define MSG_CMSG_COMPAT        0               /* We never have 32 bit fixups */
+#endif
+
+
+/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
+#define SOL_IP         0
+/* #define SOL_ICMP    1       No-no-no! Due to Linux :-) we cannot use SOL_ICMP=1 */
+#define SOL_TCP                6
+#define SOL_UDP                17
+#define SOL_IPV6       41
+#define SOL_ICMPV6     58
+#define SOL_SCTP       132
+#define SOL_UDPLITE    136     /* UDP-Lite (RFC 3828) */
+#define SOL_RAW                255
+#define SOL_IPX                256
+#define SOL_AX25       257
+#define SOL_ATALK      258
+#define SOL_NETROM     259
+#define SOL_ROSE       260
+#define SOL_DECNET     261
+#define        SOL_X25         262
+#define SOL_PACKET     263
+#define SOL_ATM                264     /* ATM layer (cell level) */
+#define SOL_AAL                265     /* ATM Adaption Layer (packet level) */
+#define SOL_IRDA        266
+#define SOL_NETBEUI    267
+#define SOL_LLC                268
+#define SOL_DCCP       269
+#define SOL_NETLINK    270
+#define SOL_TIPC       271
+#define SOL_RXRPC      272
+#define SOL_PPPOL2TP   273
+#define SOL_BLUETOOTH  274
+#define SOL_PNPIPE     275
+#define SOL_RDS                276
+#define SOL_IUCV       277
+#define SOL_CAIF       278
+#define SOL_ALG                279
+#define SOL_NFC                280
+#define SOL_KCM                281
+#define SOL_TLS                282
+#define SOL_XDP                283
+
+/* IPX options */
+#define IPX_TYPE       1
+
+extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
+extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
+
+struct timespec64;
+struct __kernel_timespec;
+struct old_timespec32;
+
+struct scm_timestamping_internal {
+       struct timespec64 ts[3];
+};
+
+extern void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss);
+extern void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_internal *tss);
+
+/* The __sys_...msg variants allow MSG_CMSG_COMPAT iff
+ * forbid_cmsg_compat==false
+ */
+extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg,
+                         unsigned int flags, bool forbid_cmsg_compat);
+extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg,
+                         unsigned int flags, bool forbid_cmsg_compat);
+extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
+                         unsigned int vlen, unsigned int flags,
+                         struct __kernel_timespec __user *timeout,
+                         struct old_timespec32 __user *timeout32);
+extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
+                         unsigned int vlen, unsigned int flags,
+                         bool forbid_cmsg_compat);
+extern long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
+                              unsigned int flags);
+extern long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
+                              struct user_msghdr __user *umsg,
+                              struct sockaddr __user *uaddr,
+                              unsigned int flags);
+extern int sendmsg_copy_msghdr(struct msghdr *msg,
+                              struct user_msghdr __user *umsg, unsigned flags,
+                              struct iovec **iov);
+extern int recvmsg_copy_msghdr(struct msghdr *msg,
+                              struct user_msghdr __user *umsg, unsigned flags,
+                              struct sockaddr __user **uaddr,
+                              struct iovec **iov);
+extern int __copy_msghdr_from_user(struct msghdr *kmsg,
+                                  struct user_msghdr __user *umsg,
+                                  struct sockaddr __user **save_addr,
+                                  struct iovec __user **uiov, size_t *nsegs);
+
+/* helpers which do the actual work for syscalls */
+extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
+                         unsigned int flags, struct sockaddr __user *addr,
+                         int __user *addr_len);
+extern int __sys_sendto(int fd, void __user *buff, size_t len,
+                       unsigned int flags, struct sockaddr __user *addr,
+                       int addr_len);
+extern int __sys_accept4_file(struct file *file, unsigned file_flags,
+                       struct sockaddr __user *upeer_sockaddr,
+                        int __user *upeer_addrlen, int flags,
+                        unsigned long nofile);
+extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
+                        int __user *upeer_addrlen, int flags);
+extern int __sys_socket(int family, int type, int protocol);
+extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
+extern int __sys_connect_file(struct file *file, struct sockaddr_storage *addr,
+                             int addrlen, int file_flags);
+extern int __sys_connect(int fd, struct sockaddr __user *uservaddr,
+                        int addrlen);
+extern int __sys_listen(int fd, int backlog);
+extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
+                            int __user *usockaddr_len);
+extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
+                            int __user *usockaddr_len);
+extern int __sys_socketpair(int family, int type, int protocol,
+                           int __user *usockvec);
+extern int __sys_shutdown(int fd, int how);
+
+extern struct ns_common *get_net_ns(struct ns_common *ns);
+#endif /* _LINUX_SOCKET_H */
index e0c13e6..cd11063 100644 (file)
@@ -7,14 +7,7 @@
 #include <sys/un.h>
 #include <arpa/inet.h>
 
-static const char *socket_families[] = {
-       "UNSPEC", "LOCAL", "INET", "AX25", "IPX", "APPLETALK", "NETROM",
-       "BRIDGE", "ATMPVC", "X25", "INET6", "ROSE", "DECnet", "NETBEUI",
-       "SECURITY", "KEY", "NETLINK", "PACKET", "ASH", "ECONET", "ATMSVC",
-       "RDS", "SNA", "IRDA", "PPPOX", "WANPIPE", "LLC", "IB", "CAN", "TIPC",
-       "BLUETOOTH", "IUCV", "RXRPC", "ISDN", "PHONET", "IEEE802154", "CAIF",
-       "ALG", "NFC", "VSOCK",
-};
+#include "trace/beauty/generated/socket_arrays.c"
 DEFINE_STRARRAY(socket_families, "PF_");
 
 static size_t af_inet__scnprintf(struct sockaddr *sa, char *bf, size_t size)
diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh
new file mode 100755 (executable)
index 0000000..3820e5c
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+# SPDX-License-Identifier: LGPL-2.1
+
+# This one uses a copy from the kernel sources headers that is in a
+# place used just for these tools/perf/beauty/ usage, we shouldn't not
+# put it in tools/include/linux otherwise they would be used in the
+# normal compiler building process and would drag needless stuff from the
+# kernel.
+
+# When what these scripts need is already in tools/include/ then use it,
+# otherwise grab and check the copy from the kernel sources just for these
+# string table building scripts.
+
+[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/perf/trace/beauty/include/linux/
+
+printf "static const char *socket_families[] = {\n"
+# #define AF_LOCAL     1       /* POSIX name for AF_UNIX       */
+regex='^#define[[:space:]]+AF_(\w+)[[:space:]]+([[:digit:]]+).*'
+
+egrep $regex ${header_dir}/socket.h | \
+       sed -r "s/$regex/\2 \1/g"       | \
+       xargs printf "\t[%s] = \"%s\",\n" | \
+       egrep -v "\"(UNIX|MAX)\""
+printf "};\n"
index 494626e..cd5e419 100644 (file)
@@ -117,6 +117,7 @@ endif
 perf-y += parse-branch-options.o
 perf-y += dump-insn.o
 perf-y += parse-regs-options.o
+perf-y += parse-sublevel-options.o
 perf-y += term.o
 perf-y += help-unknown-cmd.o
 perf-y += mem-events.o
index c076fc7..31207b6 100644 (file)
 #include "probe-file.h"
 #include "strlist.h"
 
+#ifdef HAVE_DEBUGINFOD_SUPPORT
+#include <elfutils/debuginfod.h>
+#endif
+
 #include <linux/ctype.h>
 #include <linux/zalloc.h>
 
@@ -636,6 +640,21 @@ static char *build_id_cache__find_debug(const char *sbuild_id,
        if (realname && access(realname, R_OK))
                zfree(&realname);
        nsinfo__mountns_exit(&nsc);
+
+#ifdef HAVE_DEBUGINFOD_SUPPORT
+        if (realname == NULL) {
+                debuginfod_client* c = debuginfod_begin();
+                if (c != NULL) {
+                        int fd = debuginfod_find_debuginfo(c,
+                                                           (const unsigned char*)sbuild_id, 0,
+                                                           &realname);
+                        if (fd >= 0)
+                                close(fd); /* retaining reference by realname */
+                        debuginfod_end(c);
+                }
+        }
+#endif
+
 out:
        free(debugfile);
        return realname;
index adb6567..5cda556 100644 (file)
@@ -20,6 +20,7 @@
 #include "target.h"
 #include "ui/helpline.h"
 #include "ui/ui.h"
+#include "util/parse-sublevel-options.h"
 
 #include <linux/ctype.h>
 
@@ -173,65 +174,37 @@ void trace_event(union perf_event *event)
                     trace_event_printer, event);
 }
 
-static struct debug_variable {
-       const char *name;
-       int *ptr;
-} debug_variables[] = {
-       { .name = "verbose",            .ptr = &verbose },
-       { .name = "ordered-events",     .ptr = &debug_ordered_events},
-       { .name = "stderr",             .ptr = &redirect_to_stderr},
-       { .name = "data-convert",       .ptr = &debug_data_convert },
-       { .name = "perf-event-open",    .ptr = &debug_peo_args },
+static struct sublevel_option debug_opts[] = {
+       { .name = "verbose",            .value_ptr = &verbose },
+       { .name = "ordered-events",     .value_ptr = &debug_ordered_events},
+       { .name = "stderr",             .value_ptr = &redirect_to_stderr},
+       { .name = "data-convert",       .value_ptr = &debug_data_convert },
+       { .name = "perf-event-open",    .value_ptr = &debug_peo_args },
        { .name = NULL, }
 };
 
 int perf_debug_option(const char *str)
 {
-       struct debug_variable *var = &debug_variables[0];
-       char *vstr, *s = strdup(str);
-       int v = 1;
-
-       vstr = strchr(s, '=');
-       if (vstr)
-               *vstr++ = 0;
-
-       while (var->name) {
-               if (!strcmp(s, var->name))
-                       break;
-               var++;
-       }
-
-       if (!var->name) {
-               pr_err("Unknown debug variable name '%s'\n", s);
-               free(s);
-               return -1;
-       }
+       int ret;
 
-       if (vstr) {
-               v = atoi(vstr);
-               /*
-                * Allow only values in range (0, 10),
-                * otherwise set 0.
-                */
-               v = (v < 0) || (v > 10) ? 0 : v;
-       }
+       ret = perf_parse_sublevel_options(str, debug_opts);
+       if (ret)
+               return ret;
 
-       if (quiet)
-               v = -1;
+       /* Allow only verbose value in range (0, 10), otherwise set 0. */
+       verbose = (verbose < 0) || (verbose > 10) ? 0 : verbose;
 
-       *var->ptr = v;
-       free(s);
        return 0;
 }
 
 int perf_quiet_option(void)
 {
-       struct debug_variable *var = &debug_variables[0];
+       struct sublevel_option *opt = &debug_opts[0];
 
        /* disable all debug messages */
-       while (var->name) {
-               *var->ptr = -1;
-               var++;
+       while (opt->name) {
+               *opt->value_ptr = -1;
+               opt++;
        }
 
        return 0;
index be991cb..5a3b475 100644 (file)
@@ -1265,7 +1265,7 @@ struct dso *dso__new_id(const char *name, struct dso_id *id)
                dso->has_build_id = 0;
                dso->has_srcline = 1;
                dso->a2l_fails = 1;
-               dso->kernel = DSO_TYPE_USER;
+               dso->kernel = DSO_SPACE__USER;
                dso->needs_swap = DSO_SWAP__UNSET;
                dso->comp = COMP_ID__NONE;
                RB_CLEAR_NODE(&dso->rb_node);
index 31c3a92..8ad17f3 100644 (file)
@@ -46,10 +46,10 @@ enum dso_binary_type {
        DSO_BINARY_TYPE__NOT_FOUND,
 };
 
-enum dso_kernel_type {
-       DSO_TYPE_USER = 0,
-       DSO_TYPE_KERNEL,
-       DSO_TYPE_GUEST_KERNEL
+enum dso_space_type {
+       DSO_SPACE__USER = 0,
+       DSO_SPACE__KERNEL,
+       DSO_SPACE__KERNEL_GUEST
 };
 
 enum dso_swap_type {
@@ -160,7 +160,7 @@ struct dso {
        void             *a2l;
        char             *symsrc_filename;
        unsigned int     a2l_fails;
-       enum dso_kernel_type    kernel;
+       enum dso_space_type     kernel;
        enum dso_swap_type      needs_swap;
        enum dso_binary_type    symtab_type;
        enum dso_binary_type    binary_type;
index 251faa9..9cf4efd 100644 (file)
@@ -2056,7 +2056,7 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev,
        struct machine *machine;
        u16 cpumode;
        struct dso *dso;
-       enum dso_kernel_type dso_type;
+       enum dso_space_type dso_space;
 
        machine = perf_session__findnew_machine(session, bev->pid);
        if (!machine)
@@ -2066,14 +2066,14 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev,
 
        switch (cpumode) {
        case PERF_RECORD_MISC_KERNEL:
-               dso_type = DSO_TYPE_KERNEL;
+               dso_space = DSO_SPACE__KERNEL;
                break;
        case PERF_RECORD_MISC_GUEST_KERNEL:
-               dso_type = DSO_TYPE_GUEST_KERNEL;
+               dso_space = DSO_SPACE__KERNEL_GUEST;
                break;
        case PERF_RECORD_MISC_USER:
        case PERF_RECORD_MISC_GUEST_USER:
-               dso_type = DSO_TYPE_USER;
+               dso_space = DSO_SPACE__USER;
                break;
        default:
                goto out;
@@ -2085,14 +2085,13 @@ static int __event_process_build_id(struct perf_record_header_build_id *bev,
 
                dso__set_build_id(dso, &bev->build_id);
 
-               if (dso_type != DSO_TYPE_USER) {
+               if (dso_space != DSO_SPACE__USER) {
                        struct kmod_path m = { .name = NULL, };
 
                        if (!kmod_path__parse_name(&m, filename) && m.kmod)
                                dso__set_module_info(dso, &m, machine);
-                       else
-                               dso->kernel = dso_type;
 
+                       dso->kernel = dso_space;
                        free(m.name);
                }
 
index 96af544..208b813 100644 (file)
@@ -703,7 +703,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,
 
                dso__set_module_info(dso, m, machine);
                dso__set_long_name(dso, strdup(filename), true);
-               dso->kernel = DSO_TYPE_KERNEL;
+               dso->kernel = DSO_SPACE__KERNEL;
        }
 
        dso__get(dso);
@@ -753,7 +753,7 @@ static int machine__process_ksymbol_register(struct machine *machine,
                struct dso *dso = dso__new(event->ksymbol.name);
 
                if (dso) {
-                       dso->kernel = DSO_TYPE_KERNEL;
+                       dso->kernel = DSO_SPACE__KERNEL;
                        map = map__new2(0, dso);
                }
 
@@ -971,14 +971,14 @@ static struct dso *machine__get_kernel(struct machine *machine)
                        vmlinux_name = symbol_conf.vmlinux_name;
 
                kernel = machine__findnew_kernel(machine, vmlinux_name,
-                                                "[kernel]", DSO_TYPE_KERNEL);
+                                                "[kernel]", DSO_SPACE__KERNEL);
        } else {
                if (symbol_conf.default_guest_vmlinux_name)
                        vmlinux_name = symbol_conf.default_guest_vmlinux_name;
 
                kernel = machine__findnew_kernel(machine, vmlinux_name,
                                                 "[guest.kernel]",
-                                                DSO_TYPE_GUEST_KERNEL);
+                                                DSO_SPACE__KERNEL_GUEST);
        }
 
        if (kernel != NULL && (!kernel->has_build_id))
@@ -1606,7 +1606,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
                                              union perf_event *event)
 {
        struct map *map;
-       enum dso_kernel_type kernel_type;
+       enum dso_space_type dso_space;
        bool is_kernel_mmap;
 
        /* If we have maps from kcore then we do not need or want any others */
@@ -1614,9 +1614,9 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
                return 0;
 
        if (machine__is_host(machine))
-               kernel_type = DSO_TYPE_KERNEL;
+               dso_space = DSO_SPACE__KERNEL;
        else
-               kernel_type = DSO_TYPE_GUEST_KERNEL;
+               dso_space = DSO_SPACE__KERNEL_GUEST;
 
        is_kernel_mmap = memcmp(event->mmap.filename,
                                machine->mmap_name,
@@ -1676,7 +1676,7 @@ static int machine__process_kernel_mmap_event(struct machine *machine,
                if (kernel == NULL)
                        goto out_problem;
 
-               kernel->kernel = kernel_type;
+               kernel->kernel = dso_space;
                if (__machine__create_kernel_maps(machine, kernel) < 0) {
                        dso__put(kernel);
                        goto out_problem;
index f9dc8c5..1d72108 100644 (file)
@@ -486,7 +486,7 @@ u64 map__rip_2objdump(struct map *map, u64 rip)
         * kernel modules also have DSO_TYPE_USER in dso->kernel,
         * but all kernel modules are ET_REL, so won't get here.
         */
-       if (map->dso->kernel == DSO_TYPE_USER)
+       if (map->dso->kernel == DSO_SPACE__USER)
                return rip + map->dso->text_offset;
 
        return map->unmap_ip(map, rip) - map->reloc;
@@ -516,7 +516,7 @@ u64 map__objdump_2mem(struct map *map, u64 ip)
         * kernel modules also have DSO_TYPE_USER in dso->kernel,
         * but all kernel modules are ET_REL, so won't get here.
         */
-       if (map->dso->kernel == DSO_TYPE_USER)
+       if (map->dso->kernel == DSO_SPACE__USER)
                return map->unmap_ip(map, ip - map->dso->text_offset);
 
        return ip + map->reloc;
diff --git a/tools/perf/util/parse-sublevel-options.c b/tools/perf/util/parse-sublevel-options.c
new file mode 100644 (file)
index 0000000..a841d17
--- /dev/null
@@ -0,0 +1,70 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "util/debug.h"
+#include "util/parse-sublevel-options.h"
+
+static int parse_one_sublevel_option(const char *str,
+                                    struct sublevel_option *opts)
+{
+       struct sublevel_option *opt = opts;
+       char *vstr, *s = strdup(str);
+       int v = 1;
+
+       if (!s) {
+               pr_err("no memory\n");
+               return -1;
+       }
+
+       vstr = strchr(s, '=');
+       if (vstr)
+               *vstr++ = 0;
+
+       while (opt->name) {
+               if (!strcmp(s, opt->name))
+                       break;
+               opt++;
+       }
+
+       if (!opt->name) {
+               pr_err("Unknown option name '%s'\n", s);
+               free(s);
+               return -1;
+       }
+
+       if (vstr)
+               v = atoi(vstr);
+
+       *opt->value_ptr = v;
+       free(s);
+       return 0;
+}
+
+/* parse options like --foo a=<n>,b,c... */
+int perf_parse_sublevel_options(const char *str, struct sublevel_option *opts)
+{
+       char *s = strdup(str);
+       char *p = NULL;
+       int ret;
+
+       if (!s) {
+               pr_err("no memory\n");
+               return -1;
+       }
+
+       p = strtok(s, ",");
+       while (p) {
+               ret = parse_one_sublevel_option(p, opts);
+               if (ret) {
+                       free(s);
+                       return ret;
+               }
+
+               p = strtok(NULL, ",");
+       }
+
+       free(s);
+       return 0;
+}
diff --git a/tools/perf/util/parse-sublevel-options.h b/tools/perf/util/parse-sublevel-options.h
new file mode 100644 (file)
index 0000000..9b9efcc
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _PERF_PARSE_SUBLEVEL_OPTIONS_H
+#define _PERF_PARSE_SUBLEVEL_OPTIONS_H
+
+struct sublevel_option {
+       const char *name;
+       int *value_ptr;
+};
+
+int perf_parse_sublevel_options(const char *str, struct sublevel_option *opts);
+
+#endif
\ No newline at end of file
index 5e43054..8cc4b00 100644 (file)
@@ -789,7 +789,7 @@ int symsrc__init(struct symsrc *ss, struct dso *dso, const char *name,
        if (ss->opdshdr.sh_type != SHT_PROGBITS)
                ss->opdsec = NULL;
 
-       if (dso->kernel == DSO_TYPE_USER)
+       if (dso->kernel == DSO_SPACE__USER)
                ss->adjust_symbols = true;
        else
                ss->adjust_symbols = elf__needs_adjust_symbols(ehdr);
@@ -872,7 +872,7 @@ static int dso__process_kernel_symbol(struct dso *dso, struct map *map,
                 * kallsyms and identity maps.  Overwrite it to
                 * map to the kernel dso.
                 */
-               if (*remap_kernel && dso->kernel) {
+               if (*remap_kernel && dso->kernel && !kmodule) {
                        *remap_kernel = false;
                        map->start = shdr->sh_addr + ref_reloc(kmap);
                        map->end = map->start + shdr->sh_size;
@@ -1068,7 +1068,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
         * Initial kernel and module mappings do not map to the dso.
         * Flag the fixups.
         */
-       if (dso->kernel || kmodule) {
+       if (dso->kernel) {
                remap_kernel = true;
                adjust_kernel_syms = dso->adjust_symbols;
        }
@@ -1130,7 +1130,7 @@ int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
                    (sym.st_value & 1))
                        --sym.st_value;
 
-               if (dso->kernel || kmodule) {
+               if (dso->kernel) {
                        if (dso__process_kernel_symbol(dso, map, &sym, &shdr, kmaps, kmap, &curr_dso, &curr_map,
                                                       section_name, adjust_kernel_syms, kmodule, &remap_kernel))
                                goto out_elf_end;
index 053468f..1f5fcb8 100644 (file)
@@ -808,7 +808,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
 
                        if (strcmp(curr_map->dso->short_name, module)) {
                                if (curr_map != initial_map &&
-                                   dso->kernel == DSO_TYPE_GUEST_KERNEL &&
+                                   dso->kernel == DSO_SPACE__KERNEL_GUEST &&
                                    machine__is_default_guest(machine)) {
                                        /*
                                         * We assume all symbols of a module are
@@ -865,7 +865,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta,
                                goto add_symbol;
                        }
 
-                       if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
+                       if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
                                snprintf(dso_name, sizeof(dso_name),
                                        "[guest.kernel].%d",
                                        kernel_range++);
@@ -909,7 +909,7 @@ discard_symbol:
        }
 
        if (curr_map != initial_map &&
-           dso->kernel == DSO_TYPE_GUEST_KERNEL &&
+           dso->kernel == DSO_SPACE__KERNEL_GUEST &&
            machine__is_default_guest(kmaps->machine)) {
                dso__set_loaded(curr_map->dso);
        }
@@ -1387,7 +1387,7 @@ static int dso__load_kcore(struct dso *dso, struct map *map,
         * Set the data type and long name so that kcore can be read via
         * dso__data_read_addr().
         */
-       if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
+       if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
                dso->binary_type = DSO_BINARY_TYPE__GUEST_KCORE;
        else
                dso->binary_type = DSO_BINARY_TYPE__KCORE;
@@ -1451,7 +1451,7 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename,
        symbols__fixup_end(&dso->symbols);
        symbols__fixup_duplicate(&dso->symbols);
 
-       if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
+       if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
                dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;
        else
                dso->symtab_type = DSO_BINARY_TYPE__KALLSYMS;
@@ -1537,17 +1537,17 @@ static bool dso__is_compatible_symtab_type(struct dso *dso, bool kmod,
        case DSO_BINARY_TYPE__MIXEDUP_UBUNTU_DEBUGINFO:
        case DSO_BINARY_TYPE__BUILDID_DEBUGINFO:
        case DSO_BINARY_TYPE__OPENEMBEDDED_DEBUGINFO:
-               return !kmod && dso->kernel == DSO_TYPE_USER;
+               return !kmod && dso->kernel == DSO_SPACE__USER;
 
        case DSO_BINARY_TYPE__KALLSYMS:
        case DSO_BINARY_TYPE__VMLINUX:
        case DSO_BINARY_TYPE__KCORE:
-               return dso->kernel == DSO_TYPE_KERNEL;
+               return dso->kernel == DSO_SPACE__KERNEL;
 
        case DSO_BINARY_TYPE__GUEST_KALLSYMS:
        case DSO_BINARY_TYPE__GUEST_VMLINUX:
        case DSO_BINARY_TYPE__GUEST_KCORE:
-               return dso->kernel == DSO_TYPE_GUEST_KERNEL;
+               return dso->kernel == DSO_SPACE__KERNEL_GUEST;
 
        case DSO_BINARY_TYPE__GUEST_KMODULE:
        case DSO_BINARY_TYPE__GUEST_KMODULE_COMP:
@@ -1650,9 +1650,9 @@ int dso__load(struct dso *dso, struct map *map)
                dso->symtab_type == DSO_BINARY_TYPE__GUEST_KMODULE_COMP;
 
        if (dso->kernel && !kmod) {
-               if (dso->kernel == DSO_TYPE_KERNEL)
+               if (dso->kernel == DSO_SPACE__KERNEL)
                        ret = dso__load_kernel_sym(dso, map);
-               else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
+               else if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
                        ret = dso__load_guest_kernel_sym(dso, map);
 
                machine = map__kmaps(map)->machine;
@@ -1882,7 +1882,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
        else
                symbol__join_symfs(symfs_vmlinux, vmlinux);
 
-       if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
+       if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
                symtab_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
        else
                symtab_type = DSO_BINARY_TYPE__VMLINUX;
@@ -1894,7 +1894,7 @@ int dso__load_vmlinux(struct dso *dso, struct map *map,
        symsrc__destroy(&ss);
 
        if (err > 0) {
-               if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
+               if (dso->kernel == DSO_SPACE__KERNEL_GUEST)
                        dso->binary_type = DSO_BINARY_TYPE__GUEST_VMLINUX;
                else
                        dso->binary_type = DSO_BINARY_TYPE__VMLINUX;
index 7afa416..284d592 100644 (file)
@@ -159,15 +159,15 @@ void test_bpf_obj_id(void)
                /* Check getting link info */
                info_len = sizeof(struct bpf_link_info) * 2;
                bzero(&link_infos[i], info_len);
-               link_infos[i].raw_tracepoint.tp_name = (__u64)&tp_name;
+               link_infos[i].raw_tracepoint.tp_name = ptr_to_u64(&tp_name);
                link_infos[i].raw_tracepoint.tp_name_len = sizeof(tp_name);
                err = bpf_obj_get_info_by_fd(bpf_link__fd(links[i]),
                                             &link_infos[i], &info_len);
                if (CHECK(err ||
                          link_infos[i].type != BPF_LINK_TYPE_RAW_TRACEPOINT ||
                          link_infos[i].prog_id != prog_infos[i].id ||
-                         link_infos[i].raw_tracepoint.tp_name != (__u64)&tp_name ||
-                         strcmp((char *)link_infos[i].raw_tracepoint.tp_name,
+                         link_infos[i].raw_tracepoint.tp_name != ptr_to_u64(&tp_name) ||
+                         strcmp(u64_to_ptr(link_infos[i].raw_tracepoint.tp_name),
                                 "sys_enter") ||
                          info_len != sizeof(struct bpf_link_info),
                          "get-link-info(fd)",
@@ -178,7 +178,7 @@ void test_bpf_obj_id(void)
                          link_infos[i].type, BPF_LINK_TYPE_RAW_TRACEPOINT,
                          link_infos[i].id,
                          link_infos[i].prog_id, prog_infos[i].id,
-                         (char *)link_infos[i].raw_tracepoint.tp_name,
+                         (const char *)u64_to_ptr(link_infos[i].raw_tracepoint.tp_name),
                          "sys_enter"))
                        goto done;
 
index cb33a7e..39fb81d 100644 (file)
@@ -12,15 +12,16 @@ void btf_dump_printf(void *ctx, const char *fmt, va_list args)
 static struct btf_dump_test_case {
        const char *name;
        const char *file;
+       bool known_ptr_sz;
        struct btf_dump_opts opts;
 } btf_dump_test_cases[] = {
-       {"btf_dump: syntax", "btf_dump_test_case_syntax", {}},
-       {"btf_dump: ordering", "btf_dump_test_case_ordering", {}},
-       {"btf_dump: padding", "btf_dump_test_case_padding", {}},
-       {"btf_dump: packing", "btf_dump_test_case_packing", {}},
-       {"btf_dump: bitfields", "btf_dump_test_case_bitfields", {}},
-       {"btf_dump: multidim", "btf_dump_test_case_multidim", {}},
-       {"btf_dump: namespacing", "btf_dump_test_case_namespacing", {}},
+       {"btf_dump: syntax", "btf_dump_test_case_syntax", true, {}},
+       {"btf_dump: ordering", "btf_dump_test_case_ordering", false, {}},
+       {"btf_dump: padding", "btf_dump_test_case_padding", true, {}},
+       {"btf_dump: packing", "btf_dump_test_case_packing", true, {}},
+       {"btf_dump: bitfields", "btf_dump_test_case_bitfields", true, {}},
+       {"btf_dump: multidim", "btf_dump_test_case_multidim", false, {}},
+       {"btf_dump: namespacing", "btf_dump_test_case_namespacing", false, {}},
 };
 
 static int btf_dump_all_types(const struct btf *btf,
@@ -62,6 +63,18 @@ static int test_btf_dump_case(int n, struct btf_dump_test_case *t)
                goto done;
        }
 
+       /* tests with t->known_ptr_sz have no "long" or "unsigned long" type,
+        * so it's impossible to determine correct pointer size; but if they
+        * do, it should be 8 regardless of host architecture, becaues BPF
+        * target is always 64-bit
+        */
+       if (!t->known_ptr_sz) {
+               btf__set_pointer_size(btf, 8);
+       } else {
+               CHECK(btf__pointer_size(btf) != 8, "ptr_sz", "exp %d, got %zu\n",
+                     8, btf__pointer_size(btf));
+       }
+
        snprintf(out_file, sizeof(out_file), "/tmp/%s.output.XXXXXX", t->file);
        fd = mkstemp(out_file);
        if (CHECK(fd < 0, "create_tmp", "failed to create file: %d\n", fd)) {
index b093787..1931a15 100644 (file)
@@ -159,8 +159,8 @@ void test_core_extern(void)
                exp = (uint64_t *)&t->data;
                for (j = 0; j < n; j++) {
                        CHECK(got[j] != exp[j], "check_res",
-                             "result #%d: expected %lx, but got %lx\n",
-                              j, exp[j], got[j]);
+                             "result #%d: expected %llx, but got %llx\n",
+                              j, (__u64)exp[j], (__u64)got[j]);
                }
 cleanup:
                test_core_extern__destroy(skel);
index 084ed26..a54eafc 100644 (file)
                .union_sz = sizeof(((type *)0)->union_field),           \
                .arr_sz = sizeof(((type *)0)->arr_field),               \
                .arr_elem_sz = sizeof(((type *)0)->arr_field[0]),       \
-               .ptr_sz = sizeof(((type *)0)->ptr_field),               \
-               .enum_sz = sizeof(((type *)0)->enum_field),     \
+               .ptr_sz = 8, /* always 8-byte pointer for BPF */        \
+               .enum_sz = sizeof(((type *)0)->enum_field),             \
        }
 
 #define SIZE_CASE(name) {                                              \
@@ -432,20 +432,20 @@ static struct core_reloc_test_case test_cases[] = {
                .sb4 = -1,
                .sb20 = -0x17654321,
                .u32 = 0xBEEF,
-               .s32 = -0x3FEDCBA987654321,
+               .s32 = -0x3FEDCBA987654321LL,
        }),
        BITFIELDS_CASE(bitfields___bitfield_vs_int, {
-               .ub1 = 0xFEDCBA9876543210,
+               .ub1 = 0xFEDCBA9876543210LL,
                .ub2 = 0xA6,
-               .ub7 = -0x7EDCBA987654321,
-               .sb4 = -0x6123456789ABCDE,
-               .sb20 = 0xD00D,
+               .ub7 = -0x7EDCBA987654321LL,
+               .sb4 = -0x6123456789ABCDELL,
+               .sb20 = 0xD00DLL,
                .u32 = -0x76543,
-               .s32 = 0x0ADEADBEEFBADB0B,
+               .s32 = 0x0ADEADBEEFBADB0BLL,
        }),
        BITFIELDS_CASE(bitfields___just_big_enough, {
-               .ub1 = 0xF,
-               .ub2 = 0x0812345678FEDCBA,
+               .ub1 = 0xFLL,
+               .ub2 = 0x0812345678FEDCBALL,
        }),
        BITFIELDS_ERR_CASE(bitfields___err_too_big_bitfield),
 
index a895bfe..197d0d2 100644 (file)
@@ -16,7 +16,7 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
        __u32 duration = 0, retval;
        struct bpf_map *data_map;
        const int zero = 0;
-       u64 *result = NULL;
+       __u64 *result = NULL;
 
        err = bpf_prog_load(target_obj_file, BPF_PROG_TYPE_UNSPEC,
                            &pkt_obj, &pkt_fd);
@@ -29,7 +29,7 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
 
        link = calloc(sizeof(struct bpf_link *), prog_cnt);
        prog = calloc(sizeof(struct bpf_program *), prog_cnt);
-       result = malloc((prog_cnt + 32 /* spare */) * sizeof(u64));
+       result = malloc((prog_cnt + 32 /* spare */) * sizeof(__u64));
        if (CHECK(!link || !prog || !result, "alloc_memory",
                  "failed to alloc memory"))
                goto close_prog;
@@ -72,7 +72,7 @@ static void test_fexit_bpf2bpf_common(const char *obj_file,
                goto close_prog;
 
        for (i = 0; i < prog_cnt; i++)
-               if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %ld\n",
+               if (CHECK(result[i] != 1, "result", "fexit_bpf2bpf failed err %llu\n",
                          result[i]))
                        goto close_prog;
 
index f11f187..cd6dc80 100644 (file)
@@ -591,7 +591,7 @@ void test_flow_dissector(void)
                CHECK_ATTR(tattr.data_size_out != sizeof(flow_keys) ||
                           err || tattr.retval != 1,
                           tests[i].name,
-                          "err %d errno %d retval %d duration %d size %u/%lu\n",
+                          "err %d errno %d retval %d duration %d size %u/%zu\n",
                           err, errno, tattr.retval, tattr.duration,
                           tattr.data_size_out, sizeof(flow_keys));
                CHECK_FLOW_KEYS(tests[i].name, flow_keys, tests[i].keys);
index e3cb62b..9efa7e5 100644 (file)
@@ -5,7 +5,7 @@
 static void test_global_data_number(struct bpf_object *obj, __u32 duration)
 {
        int i, err, map_fd;
-       uint64_t num;
+       __u64 num;
 
        map_fd = bpf_find_map(__func__, obj, "result_number");
        if (CHECK_FAIL(map_fd < 0))
@@ -14,7 +14,7 @@ static void test_global_data_number(struct bpf_object *obj, __u32 duration)
        struct {
                char *name;
                uint32_t key;
-               uint64_t num;
+               __u64 num;
        } tests[] = {
                { "relocate .bss reference",     0, 0 },
                { "relocate .data reference",    1, 42 },
@@ -32,7 +32,7 @@ static void test_global_data_number(struct bpf_object *obj, __u32 duration)
        for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
                err = bpf_map_lookup_elem(map_fd, &tests[i].key, &num);
                CHECK(err || num != tests[i].num, tests[i].name,
-                     "err %d result %lx expected %lx\n",
+                     "err %d result %llx expected %llx\n",
                      err, num, tests[i].num);
        }
 }
index 43d0b55..9c3c5c0 100644 (file)
@@ -21,7 +21,7 @@ void test_mmap(void)
        const long page_size = sysconf(_SC_PAGE_SIZE);
        int err, duration = 0, i, data_map_fd, data_map_id, tmp_fd, rdmap_fd;
        struct bpf_map *data_map, *bss_map;
-       void *bss_mmaped = NULL, *map_mmaped = NULL, *tmp1, *tmp2;
+       void *bss_mmaped = NULL, *map_mmaped = NULL, *tmp0, *tmp1, *tmp2;
        struct test_mmap__bss *bss_data;
        struct bpf_map_info map_info;
        __u32 map_info_sz = sizeof(map_info);
@@ -183,16 +183,23 @@ void test_mmap(void)
 
        /* check some more advanced mmap() manipulations */
 
+       tmp0 = mmap(NULL, 4 * page_size, PROT_READ, MAP_SHARED | MAP_ANONYMOUS,
+                         -1, 0);
+       if (CHECK(tmp0 == MAP_FAILED, "adv_mmap0", "errno %d\n", errno))
+               goto cleanup;
+
        /* map all but last page: pages 1-3 mapped */
-       tmp1 = mmap(NULL, 3 * page_size, PROT_READ, MAP_SHARED,
+       tmp1 = mmap(tmp0, 3 * page_size, PROT_READ, MAP_SHARED | MAP_FIXED,
                          data_map_fd, 0);
-       if (CHECK(tmp1 == MAP_FAILED, "adv_mmap1", "errno %d\n", errno))
+       if (CHECK(tmp0 != tmp1, "adv_mmap1", "tmp0: %p, tmp1: %p\n", tmp0, tmp1)) {
+               munmap(tmp0, 4 * page_size);
                goto cleanup;
+       }
 
        /* unmap second page: pages 1, 3 mapped */
        err = munmap(tmp1 + page_size, page_size);
        if (CHECK(err, "adv_mmap2", "errno %d\n", errno)) {
-               munmap(tmp1, map_sz);
+               munmap(tmp1, 4 * page_size);
                goto cleanup;
        }
 
@@ -201,7 +208,7 @@ void test_mmap(void)
                    MAP_SHARED | MAP_FIXED, data_map_fd, 0);
        if (CHECK(tmp2 == MAP_FAILED, "adv_mmap3", "errno %d\n", errno)) {
                munmap(tmp1, page_size);
-               munmap(tmp1 + 2*page_size, page_size);
+               munmap(tmp1 + 2*page_size, 2 * page_size);
                goto cleanup;
        }
        CHECK(tmp1 + page_size != tmp2, "adv_mmap4",
@@ -211,7 +218,7 @@ void test_mmap(void)
        tmp2 = mmap(tmp1, 4 * page_size, PROT_READ, MAP_SHARED | MAP_FIXED,
                    data_map_fd, 0);
        if (CHECK(tmp2 == MAP_FAILED, "adv_mmap5", "errno %d\n", errno)) {
-               munmap(tmp1, 3 * page_size); /* unmap page 1 */
+               munmap(tmp1, 4 * page_size); /* unmap page 1 */
                goto cleanup;
        }
        CHECK(tmp1 != tmp2, "adv_mmap6", "tmp1: %p, tmp2: %p\n", tmp1, tmp2);
index dde2b7a..935a294 100644 (file)
@@ -28,7 +28,7 @@ void test_prog_run_xattr(void)
              "err %d errno %d retval %d\n", err, errno, tattr.retval);
 
        CHECK_ATTR(tattr.data_size_out != sizeof(pkt_v4), "data_size_out",
-             "incorrect output size, want %lu have %u\n",
+             "incorrect output size, want %zu have %u\n",
              sizeof(pkt_v4), tattr.data_size_out);
 
        CHECK_ATTR(buf[5] != 0, "overflow",
index c571584..9ff0412 100644 (file)
@@ -309,6 +309,7 @@ static void v4_to_v6(struct sockaddr_storage *ss)
        v6->sin6_addr.s6_addr[10] = 0xff;
        v6->sin6_addr.s6_addr[11] = 0xff;
        memcpy(&v6->sin6_addr.s6_addr[12], &v4.sin_addr.s_addr, 4);
+       memset(&v6->sin6_addr.s6_addr[0], 0, 10);
 }
 
 static int udp_recv_send(int server_fd)
index 25de86a..fafedda 100644 (file)
@@ -81,7 +81,7 @@ void test_skb_ctx(void)
 
        CHECK_ATTR(tattr.ctx_size_out != sizeof(skb),
                   "ctx_size_out",
-                  "incorrect output size, want %lu have %u\n",
+                  "incorrect output size, want %zu have %u\n",
                   sizeof(skb), tattr.ctx_size_out);
 
        for (i = 0; i < 5; i++)
index c75525e..dd324b4 100644 (file)
@@ -44,25 +44,25 @@ void test_varlen(void)
        CHECK_VAL(bss->payload1_len2, size2);
        CHECK_VAL(bss->total1, size1 + size2);
        CHECK(memcmp(bss->payload1, exp_str, size1 + size2), "content_check",
-             "doesn't match!");
+             "doesn't match!\n");
 
        CHECK_VAL(data->payload2_len1, size1);
        CHECK_VAL(data->payload2_len2, size2);
        CHECK_VAL(data->total2, size1 + size2);
        CHECK(memcmp(data->payload2, exp_str, size1 + size2), "content_check",
-             "doesn't match!");
+             "doesn't match!\n");
 
        CHECK_VAL(data->payload3_len1, size1);
        CHECK_VAL(data->payload3_len2, size2);
        CHECK_VAL(data->total3, size1 + size2);
        CHECK(memcmp(data->payload3, exp_str, size1 + size2), "content_check",
-             "doesn't match!");
+             "doesn't match!\n");
 
        CHECK_VAL(data->payload4_len1, size1);
        CHECK_VAL(data->payload4_len2, size2);
        CHECK_VAL(data->total4, size1 + size2);
        CHECK(memcmp(data->payload4, exp_str, size1 + size2), "content_check",
-             "doesn't match!");
+             "doesn't match!\n");
 cleanup:
        test_varlen__destroy(skel);
 }
index 34d8471..69139ed 100644 (file)
@@ -1,5 +1,10 @@
 #include <stdint.h>
 #include <stdbool.h>
+
+void preserce_ptr_sz_fn(long x) {}
+
+#define __bpf_aligned __attribute__((aligned(8)))
+
 /*
  * KERNEL
  */
@@ -444,51 +449,51 @@ struct core_reloc_primitives {
        char a;
        int b;
        enum core_reloc_primitives_enum c;
-       void *d;
-       int (*f)(const char *);
+       void *d __bpf_aligned;
+       int (*f)(const char *) __bpf_aligned;
 };
 
 struct core_reloc_primitives___diff_enum_def {
        char a;
        int b;
-       void *d;
-       int (*f)(const char *);
+       void *d __bpf_aligned;
+       int (*f)(const char *) __bpf_aligned;
        enum {
                X = 100,
                Y = 200,
-       } c; /* inline enum def with differing set of values */
+       } c __bpf_aligned; /* inline enum def with differing set of values */
 };
 
 struct core_reloc_primitives___diff_func_proto {
-       void (*f)(int); /* incompatible function prototype */
-       void *d;
-       enum core_reloc_primitives_enum c;
+       void (*f)(int) __bpf_aligned; /* incompatible function prototype */
+       void *d __bpf_aligned;
+       enum core_reloc_primitives_enum c __bpf_aligned;
        int b;
        char a;
 };
 
 struct core_reloc_primitives___diff_ptr_type {
-       const char * const d; /* different pointee type + modifiers */
-       char a;
+       const char * const d __bpf_aligned; /* different pointee type + modifiers */
+       char a __bpf_aligned;
        int b;
        enum core_reloc_primitives_enum c;
-       int (*f)(const char *);
+       int (*f)(const char *) __bpf_aligned;
 };
 
 struct core_reloc_primitives___err_non_enum {
        char a[1];
        int b;
        int c; /* int instead of enum */
-       void *d;
-       int (*f)(const char *);
+       void *d __bpf_aligned;
+       int (*f)(const char *) __bpf_aligned;
 };
 
 struct core_reloc_primitives___err_non_int {
        char a[1];
-       int *b; /* ptr instead of int */
-       enum core_reloc_primitives_enum c;
-       void *d;
-       int (*f)(const char *);
+       int *b __bpf_aligned; /* ptr instead of int */
+       enum core_reloc_primitives_enum c __bpf_aligned;
+       void *d __bpf_aligned;
+       int (*f)(const char *) __bpf_aligned;
 };
 
 struct core_reloc_primitives___err_non_ptr {
@@ -496,7 +501,7 @@ struct core_reloc_primitives___err_non_ptr {
        int b;
        enum core_reloc_primitives_enum c;
        int d; /* int instead of ptr */
-       int (*f)(const char *);
+       int (*f)(const char *) __bpf_aligned;
 };
 
 /*
@@ -507,7 +512,7 @@ struct core_reloc_mods_output {
 };
 
 typedef const int int_t;
-typedef const char *char_ptr_t;
+typedef const char *char_ptr_t __bpf_aligned;
 typedef const int arr_t[7];
 
 struct core_reloc_mods_substruct {
@@ -523,9 +528,9 @@ typedef struct {
 struct core_reloc_mods {
        int a;
        int_t b;
-       char *c;
+       char *c __bpf_aligned;
        char_ptr_t d;
-       int e[3];
+       int e[3] __bpf_aligned;
        arr_t f;
        struct core_reloc_mods_substruct g;
        core_reloc_mods_substruct_t h;
@@ -535,9 +540,9 @@ struct core_reloc_mods {
 struct core_reloc_mods___mod_swap {
        int b;
        int_t a;
-       char *d;
+       char *d __bpf_aligned;
        char_ptr_t c;
-       int f[3];
+       int f[3] __bpf_aligned;
        arr_t e;
        struct {
                int y;
@@ -555,7 +560,7 @@ typedef arr1_t arr2_t;
 typedef arr2_t arr3_t;
 typedef arr3_t arr4_t;
 
-typedef const char * const volatile fancy_char_ptr_t;
+typedef const char * const volatile fancy_char_ptr_t __bpf_aligned;
 
 typedef core_reloc_mods_substruct_t core_reloc_mods_substruct_tt;
 
@@ -567,7 +572,7 @@ struct core_reloc_mods___typedefs {
        arr4_t e;
        fancy_char_ptr_t d;
        fancy_char_ptr_t c;
-       int3_t b;
+       int3_t b __bpf_aligned;
        int3_t a;
 };
 
@@ -739,19 +744,19 @@ struct core_reloc_bitfields___bit_sz_change {
        int8_t          sb4: 1;         /*  4 ->  1 */
        int32_t         sb20: 30;       /* 20 -> 30 */
        /* non-bitfields */
-       uint16_t        u32;            /* 32 -> 16 */
-       int64_t         s32;            /* 32 -> 64 */
+       uint16_t        u32;                    /* 32 -> 16 */
+       int64_t         s32 __bpf_aligned;      /* 32 -> 64 */
 };
 
 /* turn bitfield into non-bitfield and vice versa */
 struct core_reloc_bitfields___bitfield_vs_int {
        uint64_t        ub1;            /*  3 -> 64 non-bitfield */
        uint8_t         ub2;            /* 20 ->  8 non-bitfield */
-       int64_t         ub7;            /*  7 -> 64 non-bitfield signed */
-       int64_t         sb4;            /*  4 -> 64 non-bitfield signed */
-       uint64_t        sb20;           /* 20 -> 16 non-bitfield unsigned */
-       int32_t         u32: 20;        /* 32 non-bitfield -> 20 bitfield */
-       uint64_t        s32: 60;        /* 32 non-bitfield -> 60 bitfield */
+       int64_t         ub7 __bpf_aligned;      /*  7 -> 64 non-bitfield signed */
+       int64_t         sb4 __bpf_aligned;      /*  4 -> 64 non-bitfield signed */
+       uint64_t        sb20 __bpf_aligned;     /* 20 -> 16 non-bitfield unsigned */
+       int32_t         u32: 20;                /* 32 non-bitfield -> 20 bitfield */
+       uint64_t        s32: 60 __bpf_aligned;  /* 32 non-bitfield -> 60 bitfield */
 };
 
 struct core_reloc_bitfields___just_big_enough {
index 1f1966e..3e6912e 100644 (file)
@@ -54,6 +54,7 @@ SEC("sockops")
 int bpf_testcb(struct bpf_sock_ops *skops)
 {
        char header[sizeof(struct ipv6hdr) + sizeof(struct tcphdr)];
+       struct bpf_sock_ops *reuse = skops;
        struct tcphdr *thdr;
        int good_call_rv = 0;
        int bad_call_rv = 0;
@@ -62,6 +63,46 @@ int bpf_testcb(struct bpf_sock_ops *skops)
        int v = 0;
        int op;
 
+       /* Test reading fields in bpf_sock_ops using single register */
+       asm volatile (
+               "%[reuse] = *(u32 *)(%[reuse] +96)"
+               : [reuse] "+r"(reuse)
+               :);
+
+       asm volatile (
+               "%[op] = *(u32 *)(%[skops] +96)"
+               : [op] "+r"(op)
+               : [skops] "r"(skops)
+               :);
+
+       asm volatile (
+               "r9 = %[skops];\n"
+               "r8 = *(u32 *)(r9 +164);\n"
+               "*(u32 *)(r9 +164) = r8;\n"
+               :: [skops] "r"(skops)
+               : "r9", "r8");
+
+       asm volatile (
+               "r1 = %[skops];\n"
+               "r1 = *(u64 *)(r1 +184);\n"
+               "if r1 == 0 goto +1;\n"
+               "r1 = *(u32 *)(r1 +4);\n"
+               :: [skops] "r"(skops):"r1");
+
+       asm volatile (
+               "r9 = %[skops];\n"
+               "r9 = *(u64 *)(r9 +184);\n"
+               "if r9 == 0 goto +1;\n"
+               "r9 = *(u32 *)(r9 +4);\n"
+               :: [skops] "r"(skops):"r9");
+
+       asm volatile (
+               "r1 = %[skops];\n"
+               "r2 = *(u64 *)(r1 +184);\n"
+               "if r2 == 0 goto +1;\n"
+               "r2 = *(u32 *)(r2 +4);\n"
+               :: [skops] "r"(skops):"r1", "r2");
+
        op = (int) skops->op;
 
        update_event_map(op);
index cd4b72c..913acdf 100644 (file)
@@ -15,9 +15,9 @@ int test_pid = 0;
 bool capture = false;
 
 /* .bss */
-long payload1_len1 = 0;
-long payload1_len2 = 0;
-long total1 = 0;
+__u64 payload1_len1 = 0;
+__u64 payload1_len2 = 0;
+__u64 total1 = 0;
 char payload1[MAX_LEN + MAX_LEN] = {};
 
 /* .data */
index 305fae8..c75fc64 100644 (file)
@@ -3883,7 +3883,7 @@ static int test_big_btf_info(unsigned int test_num)
        info_garbage.garbage = 0;
        err = bpf_obj_get_info_by_fd(btf_fd, info, &info_len);
        if (CHECK(err || info_len != sizeof(*info),
-                 "err:%d errno:%d info_len:%u sizeof(*info):%lu",
+                 "err:%d errno:%d info_len:%u sizeof(*info):%zu",
                  err, errno, info_len, sizeof(*info))) {
                err = -1;
                goto done;
@@ -4094,7 +4094,7 @@ static int do_test_get_info(unsigned int test_num)
        if (CHECK(err || !info.id || info_len != sizeof(info) ||
                  info.btf_size != raw_btf_size ||
                  (ret = memcmp(raw_btf, user_btf, expected_nbytes)),
-                 "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%lu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
+                 "err:%d errno:%d info.id:%u info_len:%u sizeof(info):%zu raw_btf_size:%u info.btf_size:%u expected_nbytes:%u memcmp:%d",
                  err, errno, info.id, info_len, sizeof(info),
                  raw_btf_size, info.btf_size, expected_nbytes, ret)) {
                err = -1;
@@ -4730,7 +4730,7 @@ ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
 
                nexpected_line = snprintf(expected_line, line_size,
                                          "%s%u: {%u,0,%d,0x%x,0x%x,0x%x,"
-                                         "{%lu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
+                                         "{%llu|[%u,%u,%u,%u,%u,%u,%u,%u]},%s,"
                                          "%u,0x%x,[[%d,%d],[%d,%d]]}\n",
                                          percpu_map ? "\tcpu" : "",
                                          percpu_map ? cpu : next_key,
@@ -4738,7 +4738,7 @@ ssize_t get_pprint_expected_line(enum pprint_mapv_kind_t mapv_kind,
                                          v->unused_bits2a,
                                          v->bits28,
                                          v->unused_bits2b,
-                                         v->ui64,
+                                         (__u64)v->ui64,
                                          v->ui8a[0], v->ui8a[1],
                                          v->ui8a[2], v->ui8a[3],
                                          v->ui8a[4], v->ui8a[5],
index 6e09bf7..dbb820d 100644 (file)
@@ -135,6 +135,11 @@ static inline __u64 ptr_to_u64(const void *ptr)
        return (__u64) (unsigned long) ptr;
 }
 
+static inline void *u64_to_ptr(__u64 ptr)
+{
+       return (void *) (unsigned long) ptr;
+}
+
 int bpf_find_map(const char *test, struct bpf_object *obj, const char *name);
 int compare_map_keys(int map1_fd, int map2_fd);
 int compare_stack_ips(int smap_fd, int amap_fd, int stack_trace_len);
index 94b02a1..344a99c 100644 (file)
@@ -10,3 +10,4 @@ execveat.denatured
 /recursion-depth
 xxxxxxxx*
 pipe
+S_I*.test
index 4453b8f..0a13b11 100644 (file)
@@ -3,7 +3,7 @@ CFLAGS = -Wall
 CFLAGS += -Wno-nonnull
 CFLAGS += -D_GNU_SOURCE
 
-TEST_PROGS := binfmt_script
+TEST_PROGS := binfmt_script non-regular
 TEST_GEN_PROGS := execveat
 TEST_GEN_FILES := execveat.symlink execveat.denatured script subdir pipe
 # Makefile is a run-time dependency, since it's accessed by the execveat test
@@ -11,7 +11,8 @@ TEST_FILES := Makefile
 
 TEST_GEN_PROGS += recursion-depth
 
-EXTRA_CLEAN := $(OUTPUT)/subdir.moved $(OUTPUT)/execveat.moved $(OUTPUT)/xxxxx*
+EXTRA_CLEAN := $(OUTPUT)/subdir.moved $(OUTPUT)/execveat.moved $(OUTPUT)/xxxxx*        \
+              $(OUTPUT)/S_I*.test
 
 include ../lib.mk
 
diff --git a/tools/testing/selftests/exec/non-regular.c b/tools/testing/selftests/exec/non-regular.c
new file mode 100644 (file)
index 0000000..cd3a34a
--- /dev/null
@@ -0,0 +1,196 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+
+#include "../kselftest_harness.h"
+
+/* Remove a file, ignoring the result if it didn't exist. */
+void rm(struct __test_metadata *_metadata, const char *pathname,
+       int is_dir)
+{
+       int rc;
+
+       if (is_dir)
+               rc = rmdir(pathname);
+       else
+               rc = unlink(pathname);
+
+       if (rc < 0) {
+               ASSERT_EQ(errno, ENOENT) {
+                       TH_LOG("Not ENOENT: %s", pathname);
+               }
+       } else {
+               ASSERT_EQ(rc, 0) {
+                       TH_LOG("Failed to remove: %s", pathname);
+               }
+       }
+}
+
+FIXTURE(file) {
+       char *pathname;
+       int is_dir;
+};
+
+FIXTURE_VARIANT(file)
+{
+       const char *name;
+       int expected;
+       int is_dir;
+       void (*setup)(struct __test_metadata *_metadata,
+                     FIXTURE_DATA(file) *self,
+                     const FIXTURE_VARIANT(file) *variant);
+       int major, minor, mode; /* for mknod() */
+};
+
+void setup_link(struct __test_metadata *_metadata,
+               FIXTURE_DATA(file) *self,
+               const FIXTURE_VARIANT(file) *variant)
+{
+       const char * const paths[] = {
+               "/bin/true",
+               "/usr/bin/true",
+       };
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(paths); i++) {
+               if (access(paths[i], X_OK) == 0) {
+                       ASSERT_EQ(symlink(paths[i], self->pathname), 0);
+                       return;
+               }
+       }
+       ASSERT_EQ(1, 0) {
+               TH_LOG("Could not find viable 'true' binary");
+       }
+}
+
+FIXTURE_VARIANT_ADD(file, S_IFLNK)
+{
+       .name = "S_IFLNK",
+       .expected = ELOOP,
+       .setup = setup_link,
+};
+
+void setup_dir(struct __test_metadata *_metadata,
+              FIXTURE_DATA(file) *self,
+              const FIXTURE_VARIANT(file) *variant)
+{
+       ASSERT_EQ(mkdir(self->pathname, 0755), 0);
+}
+
+FIXTURE_VARIANT_ADD(file, S_IFDIR)
+{
+       .name = "S_IFDIR",
+       .is_dir = 1,
+       .expected = EACCES,
+       .setup = setup_dir,
+};
+
+void setup_node(struct __test_metadata *_metadata,
+               FIXTURE_DATA(file) *self,
+               const FIXTURE_VARIANT(file) *variant)
+{
+       dev_t dev;
+       int rc;
+
+       dev = makedev(variant->major, variant->minor);
+       rc = mknod(self->pathname, 0755 | variant->mode, dev);
+       ASSERT_EQ(rc, 0) {
+               if (errno == EPERM)
+                       SKIP(return, "Please run as root; cannot mknod(%s)",
+                               variant->name);
+       }
+}
+
+FIXTURE_VARIANT_ADD(file, S_IFBLK)
+{
+       .name = "S_IFBLK",
+       .expected = EACCES,
+       .setup = setup_node,
+       /* /dev/loop0 */
+       .major = 7,
+       .minor = 0,
+       .mode = S_IFBLK,
+};
+
+FIXTURE_VARIANT_ADD(file, S_IFCHR)
+{
+       .name = "S_IFCHR",
+       .expected = EACCES,
+       .setup = setup_node,
+       /* /dev/zero */
+       .major = 1,
+       .minor = 5,
+       .mode = S_IFCHR,
+};
+
+void setup_fifo(struct __test_metadata *_metadata,
+               FIXTURE_DATA(file) *self,
+               const FIXTURE_VARIANT(file) *variant)
+{
+       ASSERT_EQ(mkfifo(self->pathname, 0755), 0);
+}
+
+FIXTURE_VARIANT_ADD(file, S_IFIFO)
+{
+       .name = "S_IFIFO",
+       .expected = EACCES,
+       .setup = setup_fifo,
+};
+
+FIXTURE_SETUP(file)
+{
+       ASSERT_GT(asprintf(&self->pathname, "%s.test", variant->name), 6);
+       self->is_dir = variant->is_dir;
+
+       rm(_metadata, self->pathname, variant->is_dir);
+       variant->setup(_metadata, self, variant);
+}
+
+FIXTURE_TEARDOWN(file)
+{
+       rm(_metadata, self->pathname, self->is_dir);
+}
+
+TEST_F(file, exec_errno)
+{
+       char * const argv[2] = { (char * const)self->pathname, NULL };
+
+       EXPECT_LT(execv(argv[0], argv), 0);
+       EXPECT_EQ(errno, variant->expected);
+}
+
+/* S_IFSOCK */
+FIXTURE(sock)
+{
+       int fd;
+};
+
+FIXTURE_SETUP(sock)
+{
+       self->fd = socket(AF_INET, SOCK_STREAM, 0);
+       ASSERT_GE(self->fd, 0);
+}
+
+FIXTURE_TEARDOWN(sock)
+{
+       if (self->fd >= 0)
+               ASSERT_EQ(close(self->fd), 0);
+}
+
+TEST_F(sock, exec_errno)
+{
+       char * const argv[2] = { " magic socket ", NULL };
+       char * const envp[1] = { NULL };
+
+       EXPECT_LT(fexecve(self->fd, argv, envp), 0);
+       EXPECT_EQ(errno, EACCES);
+}
+
+TEST_HARNESS_MAIN
index 18c5de5..bf361f3 100755 (executable)
@@ -180,6 +180,8 @@ setup()
                        ;;
                r[12]) ip netns exec $ns sysctl -q -w net.ipv4.ip_forward=1
                       ip netns exec $ns sysctl -q -w net.ipv4.conf.all.send_redirects=1
+                      ip netns exec $ns sysctl -q -w net.ipv4.conf.default.rp_filter=0
+                      ip netns exec $ns sysctl -q -w net.ipv4.conf.all.rp_filter=0
 
                       ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=1
                       ip netns exec $ns sysctl -q -w net.ipv6.route.mtu_expires=10
index d3e0809..a47d1d8 100755 (executable)
@@ -2,13 +2,18 @@
 # SPDX-License-Identifier: GPL-2.0
 #
 # This tests basic flowtable functionality.
-# Creates following topology:
+# Creates following default topology:
 #
 # Originator (MTU 9000) <-Router1-> MTU 1500 <-Router2-> Responder (MTU 2000)
 # Router1 is the one doing flow offloading, Router2 has no special
 # purpose other than having a link that is smaller than either Originator
 # and responder, i.e. TCPMSS announced values are too large and will still
 # result in fragmentation and/or PMTU discovery.
+#
+# You can check with different Orgininator/Link/Responder MTU eg:
+# sh nft_flowtable.sh -o1000 -l500 -r100
+#
+
 
 # Kselftest framework requirement - SKIP code is 4.
 ksft_skip=4
@@ -21,29 +26,18 @@ ns2out=""
 
 log_netns=$(sysctl -n net.netfilter.nf_log_all_netns)
 
-nft --version > /dev/null 2>&1
-if [ $? -ne 0 ];then
-       echo "SKIP: Could not run test without nft tool"
-       exit $ksft_skip
-fi
-
-ip -Version > /dev/null 2>&1
-if [ $? -ne 0 ];then
-       echo "SKIP: Could not run test without ip tool"
-       exit $ksft_skip
-fi
-
-which nc > /dev/null 2>&1
-if [ $? -ne 0 ];then
-       echo "SKIP: Could not run test without nc (netcat)"
-       exit $ksft_skip
-fi
+checktool (){
+       $1 > /dev/null 2>&1
+       if [ $? -ne 0 ];then
+               echo "SKIP: Could not $2"
+               exit $ksft_skip
+       fi
+}
 
-ip netns add nsr1
-if [ $? -ne 0 ];then
-       echo "SKIP: Could not create net namespace"
-       exit $ksft_skip
-fi
+checktool "nft --version" "run test without nft tool"
+checktool "ip -Version" "run test without ip tool"
+checktool "which nc" "run test without nc (netcat)"
+checktool "ip netns add nsr1" "create net namespace"
 
 ip netns add ns1
 ip netns add ns2
@@ -89,11 +83,24 @@ ip -net nsr2 addr add dead:2::1/64 dev veth1
 # ns2 is going via nsr2 with a smaller mtu, so that TCPMSS announced by both peers
 # is NOT the lowest link mtu.
 
-ip -net nsr1 link set veth0 mtu 9000
-ip -net ns1 link set eth0 mtu 9000
+omtu=9000
+lmtu=1500
+rmtu=2000
+
+while getopts "o:l:r:" o
+do
+       case $o in
+               o) omtu=$OPTARG;;
+               l) lmtu=$OPTARG;;
+               r) rmtu=$OPTARG;;
+       esac
+done
+
+ip -net nsr1 link set veth0 mtu $omtu
+ip -net ns1 link set eth0 mtu $omtu
 
-ip -net nsr2 link set veth1 mtu 2000
-ip -net ns2 link set eth0 mtu 2000
+ip -net nsr2 link set veth1 mtu $rmtu
+ip -net ns2 link set eth0 mtu $rmtu
 
 # transfer-net between nsr1 and nsr2.
 # these addresses are not used for connections.
@@ -147,7 +154,7 @@ table inet filter {
       # as PMTUd is off.
       # This rule is deleted for the last test, when we expect PMTUd
       # to kick in and ensure all packets meet mtu requirements.
-      meta length gt 1500 accept comment something-to-grep-for
+      meta length gt $lmtu accept comment something-to-grep-for
 
       # next line blocks connection w.o. working offload.
       # we only do this for reverse dir, because we expect packets to
@@ -243,8 +250,14 @@ test_tcp_forwarding_ip()
 
        sleep 3
 
-       kill $lpid
-       kill $cpid
+       if ps -p $lpid > /dev/null;then
+               kill $lpid
+       fi
+
+       if ps -p $cpid > /dev/null;then
+               kill $cpid
+       fi
+
        wait
 
        check_transfer "$ns1in" "$ns2out" "ns1 -> ns2"
index 535720b..7a6d402 100644 (file)
@@ -133,6 +133,8 @@ struct seccomp_data {
 #  define __NR_seccomp 348
 # elif defined(__xtensa__)
 #  define __NR_seccomp 337
+# elif defined(__sh__)
+#  define __NR_seccomp 372
 # else
 #  warning "seccomp syscall number unknown for this architecture"
 #  define __NR_seccomp 0xffff
@@ -1719,6 +1721,10 @@ TEST_F(TRACE_poke, getpid_runs_normally)
  * a2 of the current window which is not fixed.
  */
 #define SYSCALL_RET(reg) a[(reg).windowbase * 4 + 2]
+#elif defined(__sh__)
+# define ARCH_REGS     struct pt_regs
+# define SYSCALL_NUM   gpr[3]
+# define SYSCALL_RET   gpr[0]
 #else
 # error "Do not know how to find your architecture's registers and syscalls"
 #endif
@@ -1791,7 +1797,7 @@ void change_syscall(struct __test_metadata *_metadata,
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__powerpc__) || \
        defined(__s390__) || defined(__hppa__) || defined(__riscv) || \
-       defined(__xtensa__) || defined(__csky__)
+       defined(__xtensa__) || defined(__csky__) || defined(__sh__)
        {
                regs.SYSCALL_NUM = syscall;
        }